OneToMany 关系 NULL 作为外键?
OneToMany relationship NULL as the foreign key?
前言
我正在尝试 POST(插入 Postgresql 数据库)一个 JSON 格式的实体转换成一个 PHP 对象 谢谢到 FOSRestBundle route with JMSSerializerBundle。这个实体看起来像这样:
**Vote** : OneToOne Bidirectional : **Question** : OneToMany Bidirectional : Answer
此处的 JSON 有效负载:
{
"title": "string",
"description": "string",
"question": {
"id": 0,
"title": "string",
"description": "string",
"answers": [
{
"title": "string",
"description": "string"
},
{
"title": "First answer ?",
"description": "string"
}
]
}
}
问题
插入投票时,问题字段中的 vote_id
和答案中的 question_id
都为空。
当我从我的路线获取有效载荷时,它会转换为一个带有 fos_rest.request_body
的对象,这里是操作:
public function postVoteAction(Vote $vote, ConstraintViolationList $violations)
{
if (count($violations)) {
return $this->view($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$vote->setOwner($this->getUser());
$em->persist($vote);
$em->flush();
return $vote;
}
我确实得到了一个包含我的问题和答案的投票对象,但是当它被插入到数据库中时,如前所述,外键字段为 NULL。
我已经做了什么
我查看了关系并查看实体中是否存在持久化 cascade={"persist"}
// in vote
@ORM\OneToOne(targetEntity="Question", mappedBy="vote", cascade={"persist", "remove"})
private $question;
// in question
@ORM\OneToOne(targetEntity="Vote", inversedBy="question", cascade={"persist"})
@ORM\JoinColumn(name="vote_id", referencedColumnName="id")
private $vote;
@ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist", "remove"})
private $answers;
// in answer
@ORM\ManyToOne(targetEntity="Question", inversedBy="answers", cascade={"persist"})
@ORM\JoinColumn(name="question_id", referencedColumnName="id")
private $question;
我用php bin\console make:entity --regenerate
得到了所有
getters/setters。
我清除了数据库并重新生成了它。
回答
正如@yTko 所说,我忘记将引用放回我的控制器中的对象,我认为它是由 Doctrine 和 persist 创建的,所以现在这是我的工作代码:
public function postVoteAction(Vote $vote, ConstraintViolationList $violations)
{
if (count($violations)) {
return $this->view($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$vote->setOwner($this->getUser());
$question = $vote->getQuestion();
$question->setVote($vote);
foreach ($question->getAnswers() as $answer) {
$answer->setQuestion($question);
}
$em->persist($vote);
$em->flush();
return $vote;
}
我认为您只是忘记设置相关的投票和问题实例。
在您的控制器操作中,您拥有由 jms 使用您的 json 示例转换的投票对象。
因此,您需要通过调用某些设置器来手动设置它们,如下所示:
$question = $vote->getQuestion();
$question->setVote($vote);
或以这种方式修改您的二传手:
public function setQuestion(Question $question)
{
$this->question = $question;
$this->question->setVote($this);
return $this;
}
我更喜欢第一种方式,因为setter只是用于设置具体值,而不是用于修改其他对象。
前言
我正在尝试 POST(插入 Postgresql 数据库)一个 JSON 格式的实体转换成一个 PHP 对象 谢谢到 FOSRestBundle route with JMSSerializerBundle。这个实体看起来像这样:
**Vote** : OneToOne Bidirectional : **Question** : OneToMany Bidirectional : Answer
此处的 JSON 有效负载:
{
"title": "string",
"description": "string",
"question": {
"id": 0,
"title": "string",
"description": "string",
"answers": [
{
"title": "string",
"description": "string"
},
{
"title": "First answer ?",
"description": "string"
}
]
}
}
问题
插入投票时,问题字段中的 vote_id
和答案中的 question_id
都为空。
当我从我的路线获取有效载荷时,它会转换为一个带有 fos_rest.request_body
的对象,这里是操作:
public function postVoteAction(Vote $vote, ConstraintViolationList $violations)
{
if (count($violations)) {
return $this->view($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$vote->setOwner($this->getUser());
$em->persist($vote);
$em->flush();
return $vote;
}
我确实得到了一个包含我的问题和答案的投票对象,但是当它被插入到数据库中时,如前所述,外键字段为 NULL。
我已经做了什么
我查看了关系并查看实体中是否存在持久化 cascade={"persist"}
// in vote
@ORM\OneToOne(targetEntity="Question", mappedBy="vote", cascade={"persist", "remove"})
private $question;
// in question
@ORM\OneToOne(targetEntity="Vote", inversedBy="question", cascade={"persist"})
@ORM\JoinColumn(name="vote_id", referencedColumnName="id")
private $vote;
@ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist", "remove"})
private $answers;
// in answer
@ORM\ManyToOne(targetEntity="Question", inversedBy="answers", cascade={"persist"})
@ORM\JoinColumn(name="question_id", referencedColumnName="id")
private $question;
我用php bin\console make:entity --regenerate
得到了所有
getters/setters。
我清除了数据库并重新生成了它。
回答
正如@yTko 所说,我忘记将引用放回我的控制器中的对象,我认为它是由 Doctrine 和 persist 创建的,所以现在这是我的工作代码:
public function postVoteAction(Vote $vote, ConstraintViolationList $violations)
{
if (count($violations)) {
return $this->view($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$vote->setOwner($this->getUser());
$question = $vote->getQuestion();
$question->setVote($vote);
foreach ($question->getAnswers() as $answer) {
$answer->setQuestion($question);
}
$em->persist($vote);
$em->flush();
return $vote;
}
我认为您只是忘记设置相关的投票和问题实例。
在您的控制器操作中,您拥有由 jms 使用您的 json 示例转换的投票对象。
因此,您需要通过调用某些设置器来手动设置它们,如下所示:
$question = $vote->getQuestion();
$question->setVote($vote);
或以这种方式修改您的二传手:
public function setQuestion(Question $question)
{
$this->question = $question;
$this->question->setVote($this);
return $this;
}
我更喜欢第一种方式,因为setter只是用于设置具体值,而不是用于修改其他对象。