我有两个配置为User和ApiKey的实体。他们在下面有一对一的关系映射。
用户:
/**
* @var integer
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="username", type="string", length=225, unique=true)
* @Assert\NotBlank(message="Please enter a username.")
* @Assert\Length(
* min = 2,
* max = 180,
* minMessage = "Your username must be at least {{ limit }} characters",
* maxMessage = "Your username cannot be longer than {{ limit }} characters"
* )
*/
protected $username;
/**
* @ORM\Column(name="email", type="string", length=225)
* @Assert\NotBlank(message="Please enter a email.")
* @Assert\Email(message = "The email '{{ value }}' is not a valid email.")
*/
protected $email;
/**
* @ORM\Column(name="salt", type="text")
*/
protected $salt;
/**
* @ORM\Column(name="password", type="string", length=225)
* @Assert\NotBlank(message="Please enter a password.")
* @Assert\Length(
* min = 7,
* minMessage = "Your password must be at least {{ limit }} characters long."
* )
*/
protected $password;
/**
* @Assert\NotBlank(message="Please enter a confirmation password.")
*/
protected $confirmationPassword;
/**
* @ORM\Column(name="roles", type="json_array")
*/
protected $roles;
/**
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user")
* @ORM\JoinColumn(name="id", referencedColumnName="user_id")
*/
protected $apiKey;
ApiKey:
/**
* @var integer
* @ORM\Column(name="user_id", type="integer")
* @ORM\Id
*/
protected $user_id;
/**
* @var string
* @ORM\Column(name="api_key", unique=true, type="string", length=225)
* @Assert\NotBlank(message="Please enter a username.")
*/
protected $api_key;
/**
* @var string
* @ORM\Column(name="expires", type="datetime")
* @Assert\NotBlank(message="Please enter a username.")
*/
protected $expires;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="apiKey")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
但是,当我运行以下代码时:
$user = new User();
$user->setUsername($request->get('username'));
$user->setSalt(uniqid(mt_rand(), true));
$user->setPassword(hash('sha256', $user->getSalt() . $request->get('password')));
$user->setRoles(['ROLE_API']);
$apiKey = new ApiKey();
$apiKey->setUser($user);
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
我收到这个错误,我做错了什么?
执行' INSERT INTO用户(用户名,电子邮件,盐,密码,角色,ID)VALUES(?,?,?,?,?,?)'使用参数[" bobsmith"," bob@live.com" ;," 147423531058bd98d9ac9af4.48409486"," 6196012972b1294e7f3fbf9c140bc26f0bf3b354ea37d00753bc1ecba0a72866"," [ \" ROLE_API \"]",null]:SQLSTATE [23000]:完整性约束违规:1452无法添加或更新子行:外键约束失败(
app
。users
,CONSTRAINTFK_1483A5E9BF396750
外键(id
)参考api_key
(user_id
))
变化:
$user = new User();
$user->setUsername($request->get('username'));
$user->setSalt(uniqid(mt_rand(), true));
$user->setPassword(hash('sha256', $user->getSalt() . $request->get('password')));
$user->setRoles(['ROLE_API']);
$apiKey = new ApiKey();
$this->getDoctrine()->getManager()->persist($apiKey);
$apiKey->setUser($user);
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
AppBundle \ Entity \ ApiKey类型的实体缺少字段' user_id'的已分配ID。此实体的标识符生成策略要求在调用EntityManager#persist()之前填充ID字段。如果您想要自动生成标识符,则需要相应地调整元数据映射。
答案 0 :(得分:3)
这里似乎有一个级联问题。您正在将数据库中的用户保存,但该用户已链接到尚未保存在数据库中的ApiKey。要告诉玩家它需要保持它的ApiKey以及它需要在User和ApiKey之间保持持续级联
/**
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user", cascade="persist")
*/
protected $api_key;
如果您还想与用户一起删除ApiKey,您可以使用cascade={"persist", "remove"}
您可以找到有关关联here
编辑:删除了所有者方面不存在的行// @ORM\JoinColumn(name="id", referencedColumnName="user_id")
,如Chausser所评论
答案 1 :(得分:2)
这是2倍,Cyril说,但也因为你的用户类中有额外的映射:
/**
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user")
* @ORM\JoinColumn(name="id", referencedColumnName="user_id") // Remove this line
*/
protected $apiKey;
应该是:
/**
* @ORM\OneToOne(targetEntity="ApiKey", mappedBy="user")
*/
protected $apiKey;
只有实际执行映射的映射才需要连接列。通过使用mappedBy="user"
,您将告诉学说查看ApiKey类user
属性以了解如何映射此关联。在此类中包含连接列会导致问题。