Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine One-To-Many Relationship Won't Save - Integrity Constraint Violation

I'm attempting to use Doctrine ORM Associations. I've read several tutorials and the online docs, but it's not working, and I'm honestly not sure what I'm doing wrong here. Seems like my experiments with Doctrine are pretty hit or miss. Any assistance would be appreciated.

I'd like to have a User entity and UserHistory entity, which has multiple rows for a single User. That to me sounds like One-To-Many. I don't necessarily need it to be bidirectional.

The problem I'm having is adding a history item to a user results in an error when the user is saved, because the user_id column is not set in the user_history table.

Entities:

# Entity\User.php
<?php
namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 */
class User
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string",length=255)
     */
    protected $username;

    /**
     * @ORM\OneToMany(targetEntity="UserHistory", mappedBy="user", cascade={"persist","remove"})
     * @ORM\JoinColumn(name="id", referencedColumnName="user_id")
     */
    protected $history;

    public function __construct()
    {
        $this->setHistory(new ArrayCollection());
    }

    public function getHistory()
    {
        return $this->history;
    }
}

# Entity\UserHistory.php
<?php
namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="user_history")
 */
class UserHistory
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
     */
    protected $user;

    public function getUser()
    {
        return $this->user;
    }
}

In my controller, I'm trying this:

    $em = $this->getUserService()->getEntityManager();
    $user = $em->find('Picpara\Entity\User', 1);
    $history = new UserHistory();
    $user->getHistory()->add($history);
    $em->persist($user);
    $em->flush();

All of which results in an integrity constraint violation.

Doctrine\DBAL\DBALException

File: /myproject/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:91

Message:

An exception occurred while executing 'INSERT INTO user_history (user_id) VALUES (?)' with params [null]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null

Like I said, I've dug around here on SO, googled, tried moving things around in the annotations. This is as far as I get. Not sure what I'm doing wrong. Can anyone help?

like image 455
Phillip Harrington Avatar asked Mar 02 '14 03:03

Phillip Harrington


1 Answers

The problem is that you are not setting the user entity in your history class. The association stuff does not do this automatically.

class UserHistory
{
    public function setUser($user) { $this->user = $user; }

class User
{
    public function addHistory($history)
    {
        $this->history->add($history);
        $history->addUser($this);  // *** This is what you are missing
    }

// In your controller class
$user->addHistory($history);
like image 150
Cerad Avatar answered Sep 18 '22 16:09

Cerad