Symfony2's Doctrine does not create one-to-many structure for me
doctrine-orm, php, symfony
Solution
If look at the documentation of `@JoinColumn`
This annotation is used in the context of relations in @ManyToOne, @OneToOne fields and in the Context of @JoinTable nested inside a @ManyToMany. This annotation is not required. If its not specified the attributes name and referencedColumnName are inferred from the table and primary key names.
So as you are using `ManyToOne` relation your relation definition would be,
/**
* @var Users
*
* @ORM\ManyToOne(targetEntity="Users")
* @ORM\JoinColumn(name="useridx", referencedColumnName="idx")
*/
private $useridx;
Edit:
If you want to get datas from user side then you have to create OneToMany relation. e.g
In Datas.php
/**
* @var Users
*
* @ORM\ManyToOne(targetEntity="Users", inversedBy = "datas")
* @ORM\JoinColumn(name="useridx", referencedColumnName="idx")
*/
private $useridx;
And in Users.php add following line,
/**
* @ORM\OneToMany(targetEntity="Datas", mappedBy="useridx", cascade={"persist"})
*/
protected $datas;
And then do a `doctrine:generate:entities` command. To do operations on relation check this doc entry.
Problem
I have two tables. First table is `users` and second is `datas`. Datas has `useridx` column which is foreign with `user`'s `idx`. (primary unique key). These are the table structures: Table `users` ``` CREATE TABLE public.users ( idx bigint NOT NULL, "name" varchar(250) DEFAULT NULL::character varying, surname varchar(250) DEFAULT NULL::character varying, isactive boolean NOT NULL DEFAULT false, /* Keys */ CONSTRAINT users_pkey PRIMARY KEY (idx), CONSTRAINT users_idx_key UNIQUE (idx) ) WITH ( OIDS = FALSE ); ``` Table `datas`: ``` CREATE TABLE public.datas ( idx bigint NOT NULL, useridx bigint, phrase varchar(100) DEFAULT NULL::character varying, response varchar(100) DEFAULT NULL::character varying, /* Keys */ CONSTRAINT datas_pkey PRIMARY KEY (idx), CONSTRAINT datas_idx_key UNIQUE (idx), /* Foreign keys */ CONSTRAINT fk_cf180c1a262768b5 FOREIGN KEY (useridx) REFERENCES public.users(idx) ON DELETE NO ACTION ON UPDATE NO ACTION ) WITH ( OIDS = FALSE ); ``` Now when i run these commands: ``` app/console doctrine:mapping:convert yml ./src/Acme/DemoBundle/Resources/config/doctrine/metadata/orm --from-database --force ``` And; ``` app/console doctrine:mapping:import AcmeDemoBundle annotation app/console doctrine:generate:entities AcmeDemoBundle ``` I got this result: Datas.php ``` namespace Acme\DemoBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * Acme\DemoBundle\Entity\Datas * * @ORM\Table(name="datas") * @ORM\Entity */ class Datas { /** * @var bigint $idx * * @ORM\Column(name="idx", type="bigint", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="SEQUENCE") * @ORM\SequenceGenerator(sequenceName="datas_idx_seq", allocationSize="1", initialValue="1") */ private $idx; /** * @var string $phrase * * @ORM\Column(name="phrase", type="string", length=100, nullable=true) */ private $phrase; /** * @var string $response * * @ORM\Column(name="response", type="string", length=100, nullable=true) */ private $response; /** * @var Users * * @ORM\ManyToOne(targetEntity="Users") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="useridx", referencedColumnName="idx") * }) */ private $useridx; /** * Get idx * * @return bigint */ public function getIdx() { return $this->idx; } /** * Set phrase * * @param string $phrase */ public function setPhrase($phrase) { $this->phrase = $phrase; } /** * Get phrase * * @return string */ public function getPhrase() { return $this->phrase; } /** * Set response * * @param string $response */ public function setResponse($response) { $this->response = $response; } /** * Get response * * @return string */ public function getResponse() { return $this->response; } /** * Set useridx * * @param Acme\DemoBundle\Entity\Users $useridx */ public function setUseridx(\Acme\DemoBundle\Entity\Users $useridx) { $this->useridx = $useridx; } /** * Get useridx * * @return Acme\DemoBundle\Entity\Users */ public function getUseridx() { return $this->useridx; } } ?> ``` Users.php ``` <?php namespace Acme\DemoBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * Acme\DemoBundle\Entity\Users * * @ORM\Table(name="users") * @ORM\Entity */ class Users { /** * @var bigint $idx * * @ORM\Column(name="idx", type="bigint", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="SEQUENCE") * @ORM\SequenceGenerator(sequenceName="users_idx_seq", allocationSize="1", initialValue="1") */ private $idx; /** * @var string $name * * @ORM\Column(name="name", type="string", length=250, nullable=true) */ private $name; /** * @var string $surname * * @ORM\Column(name="surname", type="string", length=250, nullable=true) */ private $surname; /** * @var boolean $isactive * * @ORM\Column(name="isactive", type="boolean", nullable=false) */ private $isactive; /** * Get idx * * @return bigint */ public function getIdx() { return $this->idx; } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set surname * * @param string $surname */ public function setSurname($surname) { $this->surname = $surname; } /** * Get surname * * @return string */ public function getSurname() { return $this->surname; } /** * Set isactive * * @param boolean $isactive */ public function setIsactive($isactive) { $this->isactive = $isactive; } /** * Get isactive * * @return boolean */ public function getIsactive() { return $this->isactive; } } ?> ``` I also have yml files but i dont think they are necessary in here only PHP files i posted here. Now, when i run this command inside of my controller: ``` <?php $user = $this->getDoctrine() ->getRepository('AcmeDemoBundle:Users') ->find(24); $phrase = $user->getDatas()->getPhrase(); ?> ``` I got an error that say `Call to a member function getDatas() on a non-object...`. I know it is clear. In Users.php i don't have getDatas(). But what i read from Symfony2 and Doctrine documentation is it should be there because they are related. All i want to do is get Datas inside of Users. What is my mistake here? What im missing? Update: I added this lines to the `Users.php` ``` <?php /** * @var \Acme\DemoBundle\Entity\Datas * * @ORM\OneToMany(targetEntity="Datas", mappedBy="datas", cascade={"all"}) */ private $datas; public function __construct() { $this->datas = new \Doctrine\Common\Collections\ArrayCollection(); } /** * Add phrases * * @param Acme\DemoBundle\Entity\Datas $datas */ public function addPhrases(\Acme\DemoBundle\Entity\Datas $datas) { $this->datas[] = $datas; } /** * Get datas * * @return Doctrine\Common\Collections\Collection */ public function getDatas() { return $this->datas; } ?> ``` And these lines to the `Datas.php` ``` <?php /** * @ORM\ManyToOne(targetEntity="Users", inversedBy="users", cascade={"all"}) */ protected $users; /** * Set users * * @param Acme\DemoBundle\Entity\Users $users */ public function setUsers(\Acme\DemoBundle\Entity\Users $users) { $this->users = $users; } /** * Get users * * @return Acme\DemoBundle\Entity\Users */ public function getUsers() { return $this->users; } ?> ``` Now `getDatas()` is working but inside of it is not. (`$user->getDatas()->getPhrase();`) I am getting this error: ``` Call to undefined method Doctrine\ORM\PersistentCollection::getPhrase() ``` Conclusion: I got collection error because it returns a collection -of course-. Iterate (like foreach) it and you will access the data. (If you encounter a problem like this.)