Reputation: 367
I have a OneToOne relation in Symfony between user and student, where user is the owner, when I try to persist changes are not made in neither of sides, this is my last configuration:
<?php
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="BackendBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="Student", mappedBy="user")
*/
private $student;
public function __construct() {
}
/**
* Set student
*
* @param \BackendBundle\Entity\Student $student
*
* @return User
*/
public function setStudent(\BackendBundle\Entity\Student $student)
{
$this->student = $student;
return $this;
}
/**
* Get student
*
* @return \BackendBundle\Entity\Student
*/
public function getStudent()
{
return $this->student;
}
}
The student:
<?php
/**
* Student
*
* @ORM\Table(name="Student")
* @ORM\Entity(repositoryClass="BackendBundle\Repository\StudentRepository")
*/
class Student
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="student")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function __construct() {
}
}
and in the controller:
public function editAction(Request $request, User $user)
{
$student = new Student();
$user->setStudent($student);
$em = $this->getDoctrine()->getManager();
$em->persist($student);
$user->setStudent($student);
$em->persist($user);
$em->flush();
/.../
}
I can save both entities and changes without any exceptions, but I can't relate them, for example in view, when I do {{ user.student }}
it gives me null, and {{ student.user_id }}
also is null.
Upvotes: 2
Views: 2975
Reputation: 29912
Modify your code as follows
<?php
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="BackendBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\OneToOne(targetEntity="Student", mappedBy="user", cascade={"persist"})
*/
private $student;
// ...
/**
* Set student
*
* @param \BackendBundle\Entity\Student $student
*
* @return User
*/
public function setStudent(\BackendBundle\Entity\Student $student)
{
$this->student = $student;
$student->setUser($this);
return $this;
}
// ...
}
public function editAction(Request $request, User $user)
{
$student = new Student();
$user->setStudent($student);
$em->flush();
}
Why this edit?
Because doctrine "listen" only for changes into owning side (so Student
entity). If you want to persist user without headaches for student, you need to:
1 - Set user into student (owning side) when you set a student into user
2 - Use cascade persist on student property of user
PS.: If you retrieve user (more in general an entity) from db with doctrine (even with parameter converter) you don't need to call explicitly persist
onto this entity.
Upvotes: 7