Reputation: 113
How can I cascade a joined model with a OneToOne
relationship where by only the User
table has an auto increment strategy and the joined Profile
model must have an id that matches the User
id.
My models look like this:
Company\Model\User
:
class User
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
* @var int
*/
private $id;
/**
* @OneToOne(targetEntity="Profile", inversedBy="user", cascade={"persist"})
* @var Profile
*/
private $profile;
Company\Model\Profile
:
class Profile
{
/**
* @Id
* @OneToOne(targetEntity="User", mappedBy="profile")
* @JoinColumn(name="id")
* @var User
*/
private $user;
When persisting an instance of the User
model, it causes the following error to be output:
Entity of type Company\Model\Profile is missing an assigned ID for field 'profile'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
The doctrine documentation calls this a simple derived identity, but does not explain how to cascade it.
Upvotes: 1
Views: 356
Reputation: 113
It turns out that the answer is actually quite simple.
First the mappedBy
and inversedBy
need to be swapped around.
Secondly, when setting the Profile
on the User
you must set the user on the profile in turn.
Company\Model\User
:
class User
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
* @var int
*/
private $id;
/**
* @OneToOne(targetEntity="Profile", mappedBy="user", cascade={"persist"})
* @var Profile
*/
private $profile;
public function setProfile(Profile $profile): void
{
$this->profile = $profile;
$this->profile->setUser($this);
}
Company\Model\Profile
:
class Profile
{
/**
* @Id
* @OneToOne(targetEntity="User", inversedBy="profile")
* @JoinColumn(name="id")
* @var User
*/
private $user;
Upvotes: 4