Как я могу каскадировать объединенную модель с отношением OneToOne, когда только таблица User имеет стратегию автоматического увеличения, а объединенная модель Profile должна иметь идентификатор, соответствующий идентификатору User.
Мои модели выглядят так:
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;
При сохранении экземпляра модели User это вызывает следующую ошибку:
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.
Документация доктрины называет это простой производной идентичностью, но не объясняет, как ее каскадировать.




Оказывается, ответ на самом деле довольно прост.
Сначала необходимо поменять местами mappedBy и inversedBy.
Во-вторых, при установке Profile на User вы должны по очереди установить пользователя в профиле.
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;