I am starting my first Zend Framework + Doctrine 2 project and I have a question. I use PostgreSQL 9 and Apache 2.2 I have the following entities (the names of the entities and attributes are just for this example):
<?php
namespace Xproject\Entities;
/**
* Entity1
* @Table()
* @Entity
*/
class Entity1
{
/***
* @var integer $ent1Code
* @Column(name="ent1Code", type="integer", length=4)
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
private $ent1Code;
/**
* @var decimal $att1
* @Column(name="att1", type="decimal")
*/
private $att1;
/**
* OWNING SIDE
* @var \Doctrine\Common\Collections\ArrayCollection
* @ManyToOne(targetEntity="Entity2", inversedBy="entity1")
* @JoinColumn(name="ent2Code", referencedColumnName="ent2Code")
*/
private $entity2;
/**
* UNIDIRECTIONAL
* @var \Doctrine\Common\Collections\ArrayCollection
* @ManyToOne(targetEntity="Entity3")
* @JoinColumn(name="ent3Code", referencedColumnName="ent3Code")
*/
private $entity3;
/**
* UNIDIRECTIONAL
* @var \Doctrine\Common\Collections\ArrayCollection
* @ManyToOne(targetEntity="Entity4")
* @JoinColumn(name="ent4Code", referencedColumnName="ent4Code")
*/
private $entity4;
public function __construct() {
$this->entity2 = new \Doctrine\Common\Collections\ArrayCollection();
$this->entity3 = new \Doctrine\Common\Collections\ArrayCollection();
$this->entity4 = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getEnt1Code(){
return $this->ent1Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
public function addEntity2(Entity2 $value){
$value->addEntity1($this);
$this->entity2->add($value);
}
public function addEntity3(Entity3 $value){
$this->entity3->add($value);
}
public function addEntity4(Entity4 $value){
开发者_Go百科 $this->entity4->add($value);
}
}
<?php
namespace Xproject\Entities;
/**
* Entity2
* @Table()
* @Entity
*/
class Entity2
{
/**
* @var integer $ent2Code
* @Column(name="ent2Code", type="integer", length=4)
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
private $ent2Code;
/**
* INVERSE SIDE
* @var entity1
* @OneToMany(targetEntity="Entity1", mappedBy="entity2")
*/
private $entity1;
public function __construct() {
$this->entity1 = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getEnt2Code(){
return $this->ent2Code;
}
public function addEntity1(Entity1 $value){
$this->entity1->add($value);
}
}
<?php
namespace Xproject\Entities;
/**
* Entity3
* @Table()
* @Entity
*/
class Entity3
{
/**
* @var integer $ent3Code
* @Column(name="ent3Code", type="integer", length=4)
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
private $ent3Code;
/**
* @var string $att1
* @Column(name="att1", type="string", length=150)
*/
private $att1;
public function getEnt3Code(){
return $this->ent3Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
}
<?php
namespace Xproject\Entities;
/**
* Entity4
* @Table()
* @Entity
*/
class Entity4
{
/**
* @var integer $ent4Code
* @Column(name="ent4Code", type="integer", length=4)
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
private $ent4Code;
/**
* @var string $att1
* @Column(name="att1", type="string", length=150)
*/
private $att1;
public function getEnt4Code(){
return $this->ent4Code;
}
public function getAtt1(){
return $this->att1;
}
public function setAtt1($value){
$this->att1=$value;
}
}
Just to try if everything is working I use the following code in Xproject's indexController:
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
$this->doctrine = Zend_Registry::get('doctrine');
$this->em = $this->doctrine->getEntityManager();
}
public function indexAction()
{
$ent2 = new Xproject\Entities\Entity2();
$this->em->persist($ent2);
$ent3 = new Xproject\Entities\Entity3();
$ent3->setAtt1('xyz');
$this->em->persist($ent3);
$ent4= new Xproject\Entities\Entity4();
$ent4->setAtt1('abc');
$this->em->persist($ent4);
//1st flush
$this->em->flush();
$ent1= new Xproject\Entities\Entity1();
$ent1->setAtt1(350.00);
$ent1->addEntity2(ent2);
$ent1->addEntity3(ent3);
$ent1->addEntity4(ent4);
$this->em->persist($ent1);
//2nd flush
//$this->em->flush();
}
}
The first flush works OK and everything is saved OK into the database, but if I use both the first and the second flush, the browser indicates an Application Error and $ent1 is not saved at all into the database.
Using a var_dump($ent1) I can see that the object $ent1 state is correct (att1 and all the collections are loaded OK). Apache error log doesn't show any error or warning during the loading of this script. I definitely think I am missing some important thing here related to the ArrayCollections and how they work when you flush them. Am I missing something crucial?Your relationships are all ManyToOne, so there should be no ArrayCollections involved.
Since there are no collections, you don't want to add
stuff, you want to set
stuff:
In Entity1:
public function setEntity2(Entity2 $entity2){
$this->entity2 = $entity2
return $this;
}
In your controller:
$entity1->setEntity2($entity2);
And that's it. Your calls like $this->entity2->add() are working, because you're initializing those properties as ArrayCollections. But doctrine is just ignoring them.
In other words, for a *ToOne relationship, the object properties are just the foreign entity type. Treat them like simple values, and set them via typical set*() mutator.
精彩评论