使用来自父实体的生成值
Using generatedvalue from parent entity
我在我们的项目中有两个使用 Doctrine 的实体:
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $username;
/**
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\OneToOne(targetEntity="UserProfile", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id", unique=true)
* @var UserProfile
*/
private $profile;
//...
}
class UserProfile
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
private $user;
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $first_name = '';
/**
* @ORM\Column(type="string")
*/
private $last_name = '';
//...
}
我正在尝试使用类似以下内容在数据库中生成新行:
$user = new User();
$user->setUsername('test');
$user->setEmail('test@example.com');
$user->setPassword(password_hash('password', PASSWORD_BCRYPT));
$em->persist($user);
$em->flush();
$userProfile = new UserProfile();
$userProfile->setFirstName('test');
$userProfile->setLastName('user');
$user->setProfile($userProfile);
$em->persist($user);
$em->flush();
这会引发错误:
Fatal error: Uncaught Doctrine\ORM\ORMException: Entity of type
App\Entity\UserProfile is missing an assigned ID for field 'user'. 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. in
/home/site/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php on
line 87
如果我添加一个没有 UserProfile 的用户,这可以正常工作,并且我在数据库中得到一行 user_id 是从 MySQL 自动增量生成的。创建新配置文件时如何让 UserProfile 使用新创建的 user_id?
我是不是把协会的事情复杂化了?我应该只在 UserProfile 上创建一个 setUserId() 方法吗?
User
和 UserProfile
实体之间的关系保留在 UserProfile::user
属性 上,但是,当您调用 User::setProfile()
时,您没有设置 属性.
将您的 User::setProfile()
函数更改为以下内容:
function setProfile(UserProfile $profile): self
{
$profile->setUser($this);
$this->profile = $profile;
return $this;
}
您的映射无效。验证您的架构 - 缺少 mappedBy
和 inversedBy
。当您修复映射时,这将按预期工作。
正在 Symfony 中验证架构:
bin/console doc:sch:val
采埃孚:
php public/index.php orm:schema-tool:validate
感谢@emix 和@fubar,他们都为解决方案做出了贡献。这就是最终起作用的:
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $username;
/**
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade={"persist", "remove"})
* @var UserProfile
*/
private $profile;
//...
public function setProfile(UserProfile $profile) : self
{
$profile->setUser($this);
$this->profile = $profile;
return $this;
}
}
class UserProfile
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User", inversedBy="profile")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
private $user;
/**
* @ORM\Column(type="string")
*/
private $first_name = '';
/**
* @ORM\Column(type="string")
*/
private $last_name = '';
//...
}
其中涉及从 UserProfile
实体中删除 $user_id
并将 inversedBy 参数添加到 OneToOne。
从 User
实体中删除 JoinColumn
并修复 setProfile()
的 setter,以便在 UserProfile 实体上设置 $user
。
我在我们的项目中有两个使用 Doctrine 的实体:
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $username;
/**
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\OneToOne(targetEntity="UserProfile", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id", unique=true)
* @var UserProfile
*/
private $profile;
//...
}
class UserProfile
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
private $user;
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $first_name = '';
/**
* @ORM\Column(type="string")
*/
private $last_name = '';
//...
}
我正在尝试使用类似以下内容在数据库中生成新行:
$user = new User();
$user->setUsername('test');
$user->setEmail('test@example.com');
$user->setPassword(password_hash('password', PASSWORD_BCRYPT));
$em->persist($user);
$em->flush();
$userProfile = new UserProfile();
$userProfile->setFirstName('test');
$userProfile->setLastName('user');
$user->setProfile($userProfile);
$em->persist($user);
$em->flush();
这会引发错误:
Fatal error: Uncaught Doctrine\ORM\ORMException: Entity of type App\Entity\UserProfile is missing an assigned ID for field 'user'. 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. in /home/site/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php on line 87
如果我添加一个没有 UserProfile 的用户,这可以正常工作,并且我在数据库中得到一行 user_id 是从 MySQL 自动增量生成的。创建新配置文件时如何让 UserProfile 使用新创建的 user_id?
我是不是把协会的事情复杂化了?我应该只在 UserProfile 上创建一个 setUserId() 方法吗?
User
和 UserProfile
实体之间的关系保留在 UserProfile::user
属性 上,但是,当您调用 User::setProfile()
时,您没有设置 属性.
将您的 User::setProfile()
函数更改为以下内容:
function setProfile(UserProfile $profile): self
{
$profile->setUser($this);
$this->profile = $profile;
return $this;
}
您的映射无效。验证您的架构 - 缺少 mappedBy
和 inversedBy
。当您修复映射时,这将按预期工作。
正在 Symfony 中验证架构:
bin/console doc:sch:val
采埃孚:
php public/index.php orm:schema-tool:validate
感谢@emix 和@fubar,他们都为解决方案做出了贡献。这就是最终起作用的:
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $user_id;
/**
* @ORM\Column(type="string")
*/
private $username;
/**
* @ORM\Column(type="string")
*/
private $password;
/**
* @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade={"persist", "remove"})
* @var UserProfile
*/
private $profile;
//...
public function setProfile(UserProfile $profile) : self
{
$profile->setUser($this);
$this->profile = $profile;
return $this;
}
}
class UserProfile
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="User", inversedBy="profile")
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
*/
private $user;
/**
* @ORM\Column(type="string")
*/
private $first_name = '';
/**
* @ORM\Column(type="string")
*/
private $last_name = '';
//...
}
其中涉及从 UserProfile
实体中删除 $user_id
并将 inversedBy 参数添加到 OneToOne。
从 User
实体中删除 JoinColumn
并修复 setProfile()
的 setter,以便在 UserProfile 实体上设置 $user
。