php - OneToMany 关系 NULL 作为外键?
问题描述
前言
由于带有JMSSerializerBundle的FOSRestBundle路由,我正在尝试发布(在 Postgresql 数据库中插入)转换为 PHP 对象的 JSON 格式实体。该实体如下所示:
**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;
}
我确实得到了一个带有我的问题和答案的 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
得到所有的getter/setter。我清除了数据库并重新生成了它。
回答
正如@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 只是用于设置具体值,而不是用于修改其他对象。
推荐阅读
- java - ConcurrentHashMap compute() 方法线程安全吗?
- keycloak - 为单独的服务(前端和后端)创建客户端/领域的方法
- python - Tkinter 没有运行程序
- google-cloud-platform - gcurl:在 Google Cloud Shell 中找不到命令
- ruby-on-rails - 如何访问 webhook 发布请求的参数正文
- javascript - 如何根据环境在 nuxt.config.js 中使用不同的设置
- java - 在 Firebase RecyclerView Android Studio 中搜索
- python - 我应该如何解释 pca.components_ 的输出
- python - 过滤和排序列表
- javascript - vue-test-utils:在 v-select 的测试中未捕获更改事件