Symfony 2: Doctrine can't create relationship - php

I'm very new to Symfony 2.0 and doctrine. I have state and customer entity in different bundle. I just want to add relation between state and customer. I'm coded state and customer entities. Here is the my code:
/**
* #orm:Entity
*/
class Customer
{
/**
* #orm:Id
* #orm:Column(type="integer")
* #orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #OneToOne(targetEntity="State")
* #JoinColumn(name="state_id", referencedColumnName="id")
*/
protected $state;
}
/**
* #orm:Entity
*/
class State
{
/**
* #orm:Id
* #orm:Column(type="integer")
* #orm:GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #orm:Column(type="string", length="50")
*/
protected $name;
}
And my config file:
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
dbname: %database_name%
user: %database_user%
password: %database_password%
orm:
auto_generate_proxy_classes: %kernel.debug%
mappings:
FogCustomerBundle: { type: annotation, dir: Entity/ }
FogMainBundle: { type: annotation, dir: Entity/ }
So my problem is when I generate schema using php app/console doctrine:schema:create command tables are generated. But relationship doesn't generated /state column doesn't generead in customer table/. Why? I don't have any idea? I'll very happy for every advise and post.

You can run into that problem if you're closely following examples from the Doctrine2 documentation, because Symfony2 places all the Doctrine2 annotations into the orm namespace, which you seem to be missing on your OneToOne and JoinColumn annotations. Your code for the $state property should look like this:
/**
* #orm:OneToOne(targetEntity="State")
* #orm:JoinColumn(name="state_id", referencedColumnName="id")
*/
protected $state;
EDIT: With changes introduced in Symfony2 beta2, annotations have changed a little. Annotations need to be imported before they are used; importing Doctrine looks like this:
use Doctrine\ORM\Mapping as ORM;
Then the new usage looks like this:
/**
* #ORM\OneToOne(targetEntity="State")
* #ORM\JoinColumn(name="state_id", referencedColumnName="id")
*/
protected $state;
There is some discussion of further changes to the annotation system; if these changes are rolled out, I'll be back with another edit.

Related

doctrine:schema:update error There is no column with name '$column' on table '$table'

I've made some changes to my doctrine Entities and need to update the database and got the following error.
$ php bin/console doctrine:schema:update -vvv
[Doctrine\DBAL\Schema\SchemaException (30)]
There is no column with name 'fleet_no' on table 'fuelData'.
Exception trace:
() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php:86
Doctrine\DBAL\Schema\SchemaException::columnDoesNotExist() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php:671
Doctrine\DBAL\Schema\Table->getColumn() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:711
Doctrine\DBAL\Platforms\MySqlPlatform->getPreAlterTableAlterPrimaryKeySQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:639
Doctrine\DBAL\Platforms\MySqlPlatform->getPreAlterTableIndexForeignKeySQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php:621
Doctrine\DBAL\Platforms\MySqlPlatform->getAlterTableSQL() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php:199
Doctrine\DBAL\Schema\SchemaDiff->_toSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php:126
Doctrine\DBAL\Schema\SchemaDiff->toSaveSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php:883
Doctrine\ORM\Tools\SchemaTool->getUpdateSchemaSql() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php:115
Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand->executeSchemaCommand() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php:65
Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand->execute() at /home/sarah/workspace/telematics_tracker/vendor/doctrine/doctrine-bundle/Command/Proxy/UpdateSchemaDoctrineCommand.php:50
Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand->execute() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:261
Symfony\Component\Console\Command\Command->run() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:839
Symfony\Component\Console\Application->doRunCommand() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:185
Symfony\Component\Console\Application->doRun() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:80
Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /home/sarah/workspace/telematics_tracker/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:116
Symfony\Component\Console\Application->run() at /home/sarah/workspace/telematics_tracker/bin/console:27
Which is correct as such, since I have a column called 'fleetNo' but not one called 'fleet_no' in the 'fuelData' table. This was not one of the changes that I made either.
I have searched the project directory for any other instance of 'fleet_no' but there aren't any.
Below is a copy of the fuelData entity.
<?php
// src/AppBundle/Entity/FuelData.php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Column;
/**
* #ORM\Entity
* #ORM\Table(name="fuelData")
*
*
*/
class FuelData
{
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
* #ORM\Id
*/
public $fleetNo;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
*/
public $startDate;
/**
* #Assert\NotBlank()
* #ORM\Column(type="string")
*/
public $endDate;
/**
* Set fleetNo
*
* #param string $fleetNo
*
* #return FuelData
*/
public function setFleetNo($fleetNo)
{
$this->fleetNo = $fleetNo;
return $this;
}
/**
* Get fleetNo
*
* #return string
*/
public function getFleetNo()
{
return $this->fleetNo;
}
/**
* Set startDate
*
* #param string $startDate
*
* #return FuelData
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this;
}
/**
* Get startDate
*
* #return string
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate
*
* #param string $endDate
*
* #return FuelData
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this;
}
/**
* Get endDate
*
* #return string
*/
public function getEndDate()
{
return $this->endDate;
}
}
The only thing that I can think of is that the column name is being converted from camelCase to underscore by something.
Is there something that I have missed or should I be looking in a different place?
Below are the relevant parts of my config.yml:
doctrine:
dbal:
default_connection: maxdb
connections:
maxdb:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
foxdb:
driver: pdo_mysql
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: maxem
entity_managers:
maxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: maxdb
mappings:
AppBundle: ~
BWTCalendarBundle: ~
BWTFMBundle: ~
BWTHealthCheckBundle: ~
BWTSkytrackBundle: ~
BWTTelematicsBundle: ~
foxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: foxdb
mappings:
FoxBundle: ~
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: maxem
entity_managers:
maxem:
naming_strategy: doctrine.orm.naming_strategy.underscore
As you can see in your config you are using the UNDERSCORE naming strategy for the orm so that is what converts your field name.
You should do
app/console doctrine:schema:drop
to start off from clean then try changing the naming strategy.
In the end if you want to be sure to have the exact column name you want just add the name parameter to the colum annotation like so:
/**
* #Assert\NotBlank()
* #ORM\Column(type="string" name="fleetNo")
* #ORM\Id
*/
public $fleetNo;

Symfony2 cannot find my doctrine2 entity class in the controller - how to fix?

I'm trying to run a simple SQL statement (something like select * from table) in my Symfony2 controller but it's not working. Somehow Symfony cannot find the class.
some info:
I've tried providing the full namespace + class name and just class name in the FROM clause
I've tried DQL and QueryBuilder (see code below. option1 and option2)
AppKernel is loading my DoctrineBundle. This was already there when I use composer to create my project
I've tried auto_mapping true and false in settings.yml
snippets of my codes are below
error message:
[Semantical Error] line 0, col 14 near 'Job j ORDER BY': Error: Class 'Job' is not defined.
500 Internal Server Error - QueryException
1 linked Exception:
QueryException »
[2/2] QueryException: [Semantical Error] line 0, col 14 near 'Job j ORDER BY': Error: Class 'Job' is not defined. +
[1/2] QueryException: SELECT u FROM Job j ORDER BY j.name ASC +
settings.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver, add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
#auto_mapping: false
#mappings:
# MyAppMyBundle:
# type: annotation
# dir: Entity/
my controller
<?php
// src/MyApp/MyBundle/Controller/JobsController.php
namespace MyApp\MyBundle\Controller;
use MyApp\MyBundle\Entity\Job;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class JobsController extends Controller {
public function listAction() {
$em = $this->getDoctrine()->getEntityManager();
//$qb = $em->createQueryBuilder();
//option1
//$qb ->select("j")
// ->from("Job", "j")
// ->orderBy("j.name", "ASC");*/
//return $this->render('MyBundle:Jobs:list.html.twig', array('jobs' => $qb->getQuery()->getResult()));
//option2
$qb = $em->createQuery("SELECT u FROM Job j ORDER BY j.name ASC");
return $this->render('MyBundle:Jobs:list.html.twig', array('jobs' => $qb->getResult()));
}
}
my entity class
<?php
// src/MyApp/MyBundle/Entity/Job.php
namespace MyApp\MyBundle\Entity;
use Doctrine\ORM\Mapping;
/**
* #Mapping\Entity
* #Mapping\Table(name="jobs")
*/
class Job {
/**
* #Mapping\Column(name="job_id", type="integer")
* #Mapping\Id
* #Mapping\GeneratedValue(strategy="AUTO")
*/
protected $jobId;
/**
* #Mapping\Column(name="name", type="text")
*/
protected $name;
/**
* #Mapping\Column(name="job_desc", type="text")
*/
protected $description;
/**
* #Mapping\Column(name="personal_req", type="text")
*/
protected $requirements;
/**
* Get jobid
*
* #return integer
*/
public function getJobId() {
return $this->applicationId;
}
/**
* Set name
*
* #param \text $name
* #return Job
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return text
*/
public function getName() {
return $this->name;
}
/**
* Set description
*
* #param \text $description
* #return Job
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return text
*/
public function getDescription() {
return $this->description;
}
/**
* Set requirements
*
* #param \text $requirements
* #return Job
*/
public function setRequirements($requirements) {
$this->requirements = $requirements;
return $this;
}
/**
* Get requirements
*
* #return text
*/
public function getRequirements() {
return $this->requirements;
}
}
use the full namespace if you make a query directly with entitymanager or just MyAppMyBundle:Job
be sure that your bundle is present in AppKernel
prefer to use $em->getRepository('MyAppMyBundle:Job')->createQueryBuilder('j') or $em->getRepository('MyAppMyBundle:Job')->findBy(array(),array('name' => 'ASC')
validate your model with php app/console doctrine:mapping:info and php app/console doctrine:schema:validate
Exceptions in symfony are always perfect so keep the focus on what your exception says
verify namespace of entity class. Because no generate error when write wrong namespace, but no find entity

FOSMessageBundle - Not generating entities properly

I'm using FOSMessageBundle, and I thought i followed the instructions pretty well, but i cant seem to get the database to generate properly...
Heres my Message entity:
<?php
namespace Acme\Bundle\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use FOS\MessageBundle\Entity\Message as BaseMessage;
use FOS\MessageBundle\Model\ParticipantInterface;
/**
* Message
*
* #ORM\Entity()
* #JMS\ExclusionPolicy("All")
*/
class Message extends BaseMessage implements EntityInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #JMS\Groups({"list", "default"})
* #JMS\Expose()
*/
protected $id;
/**
* #var Thread
*
* #ORM\ManyToOne(targetEntity="Thread", inversedBy="messages", cascade={"persist"})
* #ORM\JoinColumn(name="thread_id")
* #JMS\Groups({"default"})
*/
protected $thread;
/**
* #ORM\ManyToOne(targetEntity="User")
* #var ParticipantInterface
*/
protected $sender;
/**
* #ORM\OneToMany(targetEntity="MessageMetadata", mappedBy="message", cascade={"all"})
* #var MessageMetadata
*/
protected $metadata;
}
And my config.yml
fos_message:
db_driver: orm
thread_class: Acme\Bundle\DemoBundle\Entity\Thread
message_class: Acme\Bundle\DemoBundle\Entity\Message
The issue is, my table ends up with only id, thread_id, and sender_id. Its missing the rest of the fields.
What am i missing!
check if all classes are correcly mapped :
php app/console doctrine:mapping:info
if not you have to MessageMetadata to the config file
message_class: Acme\Bundle\DemoBundle\Entity\Message
I'm not sure but in your case it seems like you have two different configurations for this entity - your annotations and xml from FOSCommentBundle
Please change your configuration to XML format, like this https://github.com/FriendsOfSymfony/FOSMessageBundle/blob/master/Resources/config/doctrine/Message.orm.xml and check again.
regards,
Merk, one of the contributors to the project pointed me at setting auto_mapping to true under the entity manager.
Once i set this, it solved my issue!
For me the auto_mapping did not work, I got the message
Unrecognized option "auto_mapping" under "doctrine.orm"
I solved the issue by adding the FOSMessageBundle like this:
orm:
auto_generate_proxy_classes: "%kernel.debug%"
default_entity_manager: default
entity_managers:
default:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: default
second_level_cache:
enabled: true
mappings:
AppBundle: ~
UserBundle: ~
FOSMessageBundle: ~

Mapping exception using Stof/Gedmo Translation

I'm migrating my Symfony 2.0 project to version 2.1rc1. After installing the stof/doctrine-extensions-bundle and the gedmo/doctrine-extensions and test my application I get the following error:
No identifier/primary key specified for Entity "Company\TestBundle\Entity\PageTranslation" sub class of "Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation". Every Entity must have an identifier/primary key.
My config.yml looks like this:
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
orm:
auto_generate_proxy_classes: %kernel.debug%
connection: default
auto_mapping: true
mappings:
gedmo_translatable:
type: annotation
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable # this one is optional and will default to the name set for the mapping
is_bundle: false
gedmo_translator:
type: annotation
prefix: Gedmo\Translator\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translator/Entity"
alias: GedmoTranslator # this one is optional and will default to the name set for the mapping
is_bundle: false
stof_doctrine_extensions:
default_locale: en
translation_fallback: true
orm:
default:
translatable: true
sluggable: true
According to the documentation of StofDoctrineExtensionsBundle this should be fine. The only thing I'm not sure of is the auto_mapping: true option.
The only code I've changed in my project is in my CategoryTranslation class. I've replaced:
use Stof\DoctrineExtensionsBundle\Entity\AbstractTranslation;
by:
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation;
Because the Stof-bundle doesn't have an AbstractTranslation class anymore.
Can someone tell me how I can fix this?
My PageTranslation entity before:
class PageTranslation extends AbstractTranslation
{
/**
* All required columns are mapped through inherited superclass
*/
}
My PageTranslation entity after generating the entities on the commandline:
class PageTranslation extends AbstractTranslation
{
/**
* All required columns are mapped through inherited superclass
*/
/**
* #var integer $id
*/
private $id;
/**
* #var string $locale
*/
private $locale;
.....etc....
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set locale
*
* #param string $locale
* #return PageTranslation
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* Get locale
*
* #return string
*/
public function getLocale()
{
return $this->locale;
}
..etc....
}
If you are using StofDoctrineExtensions you don't need gedmo/doctrine-extensions. Also isn't necessary to generate anything in PageTranslation

Symfony2.1 mapping error: class_parents()

I have a problem trying to get data from a table (via entity) using Doctrine2 in a Symfony2.1 project. Here is the controller where I get the error:
/**
* Country list
*/
public function countrylistAction()
{
$em = $this->getDoctrine()->getManager();
$countryList = $em->getRepository('ProjectBaseBundle:SYS_TCountry')
->findAll();
$serializer = new Serializer(array(new GetSetMethodNormalizer()),
array('json' => new JsonEncoder()));
return new Response($serializer->serialize($countryList, 'json'));
}
The entity:
<?php
namespace Company\Project\BaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="SYS_TCountry")
*/
class SYS_TCountry
{
/**
* #ORM\Id
* #ORM\Column(type="string", length=3, nullable=false)
* #var string
*/
protected $idcountry;
/**
* #ORM\Column(type="string", length=75, nullable=false)
* #Assert\NotBlank()
* #var string
*/
protected $name;
....
public function getIdcountry() { return $this->idcountry; }
public function getName() { return $this->name; }
public function getA2() { return $this->a2; }
public function getA3() { return $this->a3; }
public function getIdstatus() { return $this->idstatus; }
public function setIdcountry($idcountry) { $this->idcountry = $idcountry; }
public function setName($name) { $this->name = $name; }
public function setA2($a2) { $this->a2 = $a2; }
public function setA3($a3) { $this->a3 = $a3; }
public function setIdstatus($idstatus) { $this->idstatus = $idstatus; }
public function __toString() { return $this->idcountry; }
}
Config.yml:
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
And this is the error:
Warning: class_parents():
Class Company\Project\BaseBundle\Entity\SYS_TCountry does not exist and could not be loaded in
/var/www/project/src/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php line 40
It is strange because, as Doctrine says in console, the mapping is properly done: I test it executing php app/console doctrine:mapping:info:
[OK] Company\Project\BaseBundle\Entity\SYS_TCountry
and if I execute a query in console everything goes fine -> app/console doctrine:query:sql 'SELECT * FROM SYS_TCountry', that return results.
I do not know if using Symfony2.1 I have to configure something different to the 2.0 version, but seems the same because the mapping is Doctrine responsibility.
Symfony follows the PSR-0 standard for filenames. That, amongst other things, means that if you use an underscore in your class name, it will replace it with a directory separator when deciding where your class should live, like this:
\namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
So, if you have a class named SYS_TCountry it would expect to find it in
Company/Project/BaseBundle/Entity/SYS/TCountry.php
instead of
Company/Project/BaseBundle/Entity/SYS_TCountry.php
I think that your best solution would be to change the filename and class name to SYSTCountry. You don´t need to change the table name.
Your class entity name is not compliant with PSR-0 which causes the loading error.
If you rename your entity to SYSTCountry everything will work fine!
Edit: Default Symfony2 and Doctrine autoloaders ARE PSR-0 compliant.

Categories