Zend + Doctrine2: Как правильно очистить объект с помощью ArrayCollections ()? - PullRequest
0 голосов
/ 14 апреля 2011

Я начинаю свой первый проект Zend Framework + Doctrine 2, и у меня есть вопрос.Я использую PostgreSQL 9 и Apache 2.2. У меня есть следующие сущности (имена сущностей и атрибуты только для этого примера):

<?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){
    $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;
}
}

Просто чтобы попробовать, если все работает, я использую следующий код в Xproject'sindexController:

<?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();     
}
}

Первый сброс работает нормально, и все сохраняется нормально в базе данных, но если я использую как первый, так и второй сброс, браузер сообщит об ошибке приложения, а $ ent1 не сохранится ввсе в базу данных.
Используя var_dump ($ ent1), я вижу, что состояние объекта $ ent1 является правильным (att1 и все коллекции загружены в порядке).
В журнале ошибок Apache не отображается ни ошибки, нипредупреждение во время загрузки этого скрипта.
Я определенно думаю, что мне не хватает какой-то важной вещи, связанной с ArrayCollections и как они работают, когда вы их очищаете.
Я что-то упускаю из виду?

1 Ответ

1 голос
/ 16 апреля 2011

Все ваши отношения - ManyToOne, поэтому не должно быть никаких ArrayCollections.

Поскольку коллекций нет, вы не хотите add вещи, вам нужно set вещи:

в Entity1:

public function setEntity2(Entity2 $entity2){
    $this->entity2 = $entity2
    return $this;
}

ваш контроллер:

$entity1->setEntity2($entity2);

И все.Ваши вызовы типа $ this-> entity2-> add () работают, потому что вы инициализируете эти свойства как ArrayCollections.Но доктрина просто игнорирует их.

Другими словами, для отношения * ToOne свойства объекта являются просто типом внешней сущности.Обращайтесь с ними как с простыми значениями и устанавливайте их с помощью типичного мутатора set * ().

...