2014-03-02 5 views
8

Ich versuche Doctrine ORM-Zuordnungen zu verwenden. Ich habe mehrere Tutorials und Online-Dokumente gelesen, aber es funktioniert nicht, und ich bin ehrlich gesagt nicht sicher, was ich hier falsch mache. Scheint so, als ob meine Experimente mit Doctrine ziemlich gut getroffen sind. Jede Hilfe wäre willkommen.Eins-zu-viele-Beziehung der Doktrin wird nicht gespeichert - Integritätseinschränkungsverletzung

Ich möchte eine Benutzerentität und UserHistory Entität haben, die mehrere Zeilen für einen einzelnen Benutzer hat. Das klingt für mich nach One-To-Many. Ich brauche es nicht unbedingt bidirektional.

Das Problem, das ich habe, ist das Hinzufügen eines History-Elements zu einem Benutzer führt zu einem Fehler beim Speichern des Benutzers, da die Spalte user_id nicht in der user_history-Tabelle festgelegt ist.

Instanzen:

# 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 meinem Controller, ich dies versuchen:

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

All das in einer Integritätseinschränkungsverletzung führt.

Lehre \ DBAL \ DBALException

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

Nachricht:

trat eine Ausnahme Ausführen '(?) INSERT INTO user_history (user_id) VALUES' mit params [null]:

SQLSTATE [23000]: Integrität Einschränkungsverletzung: 1048 Spalte 'user_id' nicht null sein kann

Wie ich schon sagte, ich habe hier auf SO gegraben, gegoogelt, versucht, Dinge in den Anmerkungen zu bewegen. Das ist soweit ich komme. Ich bin mir nicht sicher, was ich falsch mache. Kann jemand helfen?

+0

Es ist nicht klar, was Benutzergeschichte tatsächlich eine Geschichte hält; Wenn Sie beabsichtigen, den Status eines Benutzers zu einem bestimmten Zeitpunkt zu speichern, funktioniert Ihr Ansatz nicht, da er immer auf den neuesten Benutzerdatensatz verweist. – AlexP

+0

Es tut mir leid - ich habe im Beispiel alle Felder aus beiden Entitäten entfernt, um sie sauber zu halten. Die UserHistory speichert Audit-Trail-Sachen wie: "Benutzer X hat Y auf DateTime". 'Etwas Inhalt hinzugefügt' 'Etwas bevorzugt' 'Etwas verändert'. –

Antwort

10

Das Problem besteht darin, dass Sie die Benutzerentität nicht in Ihrer Verlaufsklasse festlegen. Der Verband macht das nicht automatisch.

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); 
+0

Huzzah! Das hat es getan. Danke :-) –

+0

Willkommen. Schob mich über die 10K-Wiederholungsbarriere. – Cerad

Verwandte Themen