Reputation: 767
I have problem with inserting User entity with related entity UserProfile.
class User
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="id", type="integer", options={"unsigned"=true})
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var UserProfile
*
* @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade={"persist", "remove"})
*/
protected $profile
....
}
class UserProfile
{
/**
* @var User
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\OneToOne(targetEntity="User", inversedBy="profile" )
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
.....
}
Standard User-UserProfile bidirectional relation. When I submit form contains fields from User entity and UserProfile entity, $form->getData() gives me User object with UserProfile. So far so good.
Mysql generate a unique identity by auto-increment PK. To insert entity I have to do:
$em->persist($user)
$em->flush()
to get PK as id for persist and flush UserProfile.
But doctrine CANT insert $user because $user object has related $user->profile received from form Type:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', 'email', array('label' => 'email'))
->add('profile', new RegistrationProfileFormType(), array('required'=>true,))
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'User',
'cascade_validation'=>true,
));
}
Update: Exception msg Entity of type Entity\UserProfile has identity through a foreign entity Entity\User, however this entity has no identity itself. You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'Entity\UserProfile'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
Q: How to handle this problem properly ?
Sorry for my rusty English.
Upvotes: 1
Views: 4058
Reputation: 11364
The problem is you are going to perist objects through not owning side. Owning side is the one with "inversedBy" property. And you should persist objects that way.
You can read more about it here: http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html
So, example for your case:
$profile->setUser($user);
$em->persist($profile).
$em->flush();
Although, if you want to keep the way you already have, there are two options:
1) Make User
entity as the owning side and UserProfile
as the inverse side
or
2) In your profile setter in User
class do something like that:
public function setUserProfile(UserProfile $profile)
{
$this->profile = $profile;
$this->profile->setUser($this);
}
edit:
I've just notice that you don't have "id" field in your UserProfile
entity - probably this is the reason. the easiest way would be separate primary and foreign keys. But if you want treat foreign as primary take a look at this article: http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#identity-through-foreign-entities
Upvotes: 1