[DDC-2244] One-To-Many Cascade saving not working properly Created: 15/Jan/13  Updated: 15/Jan/13  Resolved: 15/Jan/13

Status: Closed
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Paweł Łaskarzewski Assignee: Marco Pivetta
Resolution: Invalid Votes: 0
Labels: None


 Description   

I have the following code:

$new = new InterviewReview();

$question = new InterviewReviewQuestion();
$new->addQuestion($question);

$em->persist($new);
$em->flush();

When i execute this code i have the following error:

An exception occurred while executing 'INSERT INTO interview_review_question (question, tags, created_at, interview_review_id) VALUES (?, ?, ?, ?)' with params {"1":"asdfg","2":"asdfg","3":null,"4":null}:

Column 'interview_review_id' cannot be null

Here are my entities:

/**
 * InterviewReview
 *
 * @ORM\Table(name="interview_review")
 * @ORM\Entity
 */
class InterviewReview
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Absolvent\AbsolventBundle\Entity\InterviewReviewQuestion", cascade={"persist", "remove"}, mappedBy="interview_review")
     * @ORM\JoinColumn(name="interview_review", referencedColumnName="id")
     */
    private $questions;

    /**
     * Add question
     *
     * @param \Absolvent\AbsolventBundle\Entity\InterviewReviewQuestion $question
     * @return InterviewReview
     */
    public function addQuestion(\Absolvent\AbsolventBundle\Entity\InterviewReviewQuestion $question)
    {
        $this->questions[] = $question;

        return $this;
    }

    /**
     * Remove question
     *
     * @param \Absolvent\AbsolventBundle\Entity\InterviewReviewQuestion $question
     */
    public function removeQuestion(\Absolvent\AbsolventBundle\Entity\InterviewReviewQuestion $question)
    {
        $this->questions->removeElement($question);
    }

    /**
     * Get questions
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getQuestions()
    {
        return $this->questions;
    }
}


/**
 * InterviewReviewQuestion
 *
 * @ORM\Table(name="interview_review_question")
 * @ORM\Entity
 */
class InterviewReviewQuestion
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Absolvent\AbsolventBundle\Entity\InterviewReview
     *
     * @ORM\ManyToOne(targetEntity="Absolvent\AbsolventBundle\Entity\InterviewReview", cascade={"persist", "remove"}, inversedBy="questions")
     * @ORM\JoinColumn(name="interview_review_id", referencedColumnName="id", nullable=false)
     */
    private $interview_review;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set interview_review
     *
     * @param \Absolvent\AbsolventBundle\Entity\InterviewReview $interviewReview
     * @return InterviewReviewQuestion
     */
    public function setInterviewReview(\Absolvent\AbsolventBundle\Entity\InterviewReview $interviewReview = null)
    {
        $this->interview_review = $interviewReview;

        return $this;
    }

    /**
     * Get interview_review
     *
     * @return \Absolvent\AbsolventBundle\Entity\InterviewReview
     */
    public function getInterviewReview()
    {
        return $this->interview_review;
    }
}

This problem is causing because the is no $question->setInterviewReview() called anywhere.

I know that i can call it inside addQuestion function, but is should work out of the box - isn't it?



 Comments   
Comment by Marco Pivetta [ 15/Jan/13 ]

Fixing code highlighting

Comment by Paweł Łaskarzewski [ 15/Jan/13 ]

Fixed

Comment by Marco Pivetta [ 15/Jan/13 ]

Works here with your code. What's the exact ORM version you're using?

Comment by Marco Pivetta [ 15/Jan/13 ]

Calling

$question->setInterviewReview($this);

is up to you. Doctrine does not apply this kind of "magic".
You are responsible for keeping your object graph consistent.

Comment by Paweł Łaskarzewski [ 15/Jan/13 ]

In composer (using symofny) i have:

"doctrine/orm": ">=2.2,<2.4-dev"

and got the latest version.

Lanuched composer update 2 hours ago

Comment by Paweł Łaskarzewski [ 15/Jan/13 ]

Ok but both objects are new and connected (using add function). I thought that cascade=

{"persist"}

will do this magic

Comment by Marco Pivetta [ 15/Jan/13 ]

No, associating them is up to you. The ORM is only responsible for saving/loading data, not for manipulating your associations like that.

Comment by Paweł Łaskarzewski [ 15/Jan/13 ]

In the documentation there is some info about this:

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/working-with-associations.html#transitive-persistence-cascade-operations

Even if you persist a new User that contains our new Comment this code would fail if you removed the call to EntityManager#persist($myFirstComment). Doctrine 2 does not cascade the persist operation to all nested entities that are new as well.
[....]
To have Doctrine handle both cases automatically we can change the User#commentsAuthored property to cascade both the “persist” and the “remove” operation.

Comment by Marco Pivetta [ 15/Jan/13 ]

Paweł Łaskarzewski see DDC-2227

Comment by Paweł Łaskarzewski [ 15/Jan/13 ]

Ok thanks for your help

Generated at Fri Nov 28 18:19:29 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.