OneToMany关系NULL作为外键?

时间:2019-02-19 18:22:34

标签: php postgresql symfony doctrine-orm fosrestbundle

序言


我正试图通过将FOSRestBundleJMSSerializerBundle进行路由,将JSON格式的实体过帐(插入Postgresql数据库)到PHP对象。这个实体看起来像这样:

**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来获取全部    吸气剂/设定者。 我清除了数据库并重新生成它。

答案


正如@yTko所说,我忘记了将引用放回控制器中的对象,我认为它是由Doctrine制作的,并且具有持久性,因此现在是我的工作代码:

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;
}

1 个答案:

答案 0 :(得分:1)

我认为您只是忘记设置投票和问题的相关实例。

在您的控制器操作中,有一个表决对象,该对象由json示例中的jms转换。

因此,您需要通过调用某些设置器来手动设置它们,如下所示:

$question = $vote->getQuestion();
$question->setVote($vote);

或以这种方式修改您的二传手:

public function setQuestion(Question $question)
{
    $this->question = $question;
    $this->question->setVote($this);

    return $this;
}

我更喜欢第一种方法,因为设置器仅用于设置具体值,而不用于修改其他对象。