I was hoping this be a straight forward process but it seems Doctrine doesn't really like the idea of linking entities through their IDs.
All I intended to do was normalising a table by shipping some fields from it to a new table and instead of adding a new reference field to the original table to hold the ID of the new corresponding record in the, make sure the new record in the child table will have identical ID to its parent row.
Here is an example of what I have:
A User entity, with annotated field $user
to reference column ID in the UserDetail entity to itself's ID
/**
* @ORM\Table(name="user", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"})
* @ORM\Entity
*/
class User extends Entity
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id
/**
* @ORM\OneToOne(targetEntity="UserDetail", cascade={"persist"})
* @ORM\JoinColumn(name="id", referencedColumnName="id", nullable=true)
*/
private $userDetail;
...
}
and here is the UserDetail with its ID's @GeneratedValue removed
/**
* @ORM\Table(name="user_detail", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"})
* @ORM\Entity
*/
class UserDetail extends Entity
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
*/
private $id;
...
}
At this point what my expectation was to be able to do something like:
$user = new User();
$userDetail = new UserDetail();
$user->setUserDetail($userDetail)
$entityManager->persist($user);
$entityManager->flush();
And get two records persisted to the user and user_detail tables with identical IDs, but the reality is, not having any strategy defined for the UserDetail's identifier, doctrine will complaint about the missing ID, Entity of type UserDetail is missing an assigned ID for field 'id'.
Of course it is possible to do the job manually and in more than one call
$user = new User();
$entityManager->persist($user);
$entityManager->flush();
$userDetail = new UserDetail();
$userDetail->setId($user->getId)
$user->setUserDetail($userDetail)
$entityManager->persist($user);
$entityManager->flush();
But I'm still hoping there is a correct configuration (annotation) that can help me to avoid such extra steps and leave handling of a one-to-one relationship through the entity's IDs to Doctrine.
This is untested but I think the following might work, according to the docs (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html):
/**
* @ORM\Table(name="user_detail", options={"collate"="utf8_general_ci", "charset"="utf8", "engine"="InnoDB"})
* @ORM\Entity
*/
class UserDetail extends Entity
{
/**
* @var integer
*
* @ORM\OneToOne(targetEntity="User")
* @ORM\JoinColumn(name="id", referencedColumnName="id")
* @ORM\Id
*/
private $user;
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With