2013-09-02 2 views
1

Когда я удаляю объект, отношения OneToOne не удаляются. Галерея успешно удалена из базы данных, но largeImage, mediumImage и smallImage нет.Doctrine OneToOne удалить объект

Что я делаю неправильно?

Удаление действия в контроллере:

public function deleteAction($id) 
{ 
    $em = $this->getDoctrine()->getManager(); 
    $offer = $em->getRepository('ToCmsBundle:Offer')->find($id); 

    if($offer) { 

     if(!$offer->getGallery()->isEmpty()) { 
      foreach($offer->getGallery() as $key => $image) { 
       $image->setOffer(null); 
       $offer->removeGallery($image); 
       //$em->remove($image); 
       //$em->flush(); 
       echo $image->getPath() . '<br/>'; 
      } 
     } else { 
      echo 'gallery is empty'; 
     } 

     $offer->setLargeImage(null); 
     $offer->setMediumImage(null); 
     $offer->setSmallImage(null); 

     $em->remove($offer); 

     $em->flush(); 
    } 

    return $this->redirect($this->generateUrl('to_offer_list')); 
} 

Мой владелец класса:

/** 
* Offer 
* 
* @ORM\Table(name="to_offer") 
* @ORM\HasLifecycleCallbacks 
* @ORM\Entity(repositoryClass="To\CmsBundle\Repository\OfferRepository") 
*/ 
class Offer { 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="title", type="string", length=255) 
    */ 
    private $title; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="content", type="text") 
    */ 
    private $content; 

    /** 
    * @var ArrayCollection 
    * 
    * @ORM\OneToMany(targetEntity="Image", mappedBy="offer", cascade={"all"}, orphanRemoval=true) 
    */ 
    private $gallery; 

    /** 
    * @var Image 
    * 
    * @ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true) 
    */ 
    public $largeImage; 

    /** 
    * @var Image 
    * 
    * @ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true) 
    */ 
    public $mediumImage; 

    /** 
    * @var Image 
    * 
    * @ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true) 
    */ 
    public $smallImage; 

    /** 
    * @var ArrayCollection 
    * 
    * @ORM\ManyToMany(targetEntity="Category", inversedBy="articles") 
    * @ORM\JoinTable(name="to_articles_categories") 
    */ 
    private $categories; 

    /** 
    * @var User 
    * 
    * @ORM\ManyToOne(targetEntity="User") 
    * @ORM\JoinColumn(name="author_id", referencedColumnName="id") 
    */ 
    private $author; 

    public function __construct() { 
     $this->gallery = new ArrayCollection(); 
     $this->categories = new ArrayCollection(); 
    } 

    /** other stuff */ 
} 

класс Image:

/** 
* Image 
* 
* @ORM\Table(name="to_images") 
* @ORM\Entity(repositoryClass="To\CmsBundle\Repository\ImageRepository") 
* @ORM\HasLifecycleCallbacks 
*/ 
class Image 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="hashName", type="string", length=255) 
    */ 
    private $hashName; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="position", type="integer") 
    */ 
    private $position; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="path", type="string", length=255) 
    */ 
    private $path; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="thumbnail", type="string", length=255) 
    */ 
    private $thumbnail; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="originalImage", type="string", length=255) 
    */ 
    private $originalImage; 

    /** 
    * @var Offer 
    * 
    * @ORM\ManyToOne(targetEntity="Offer", inversedBy="gallery") 
    * @ORM\JoinColumn(name="offer_id", referencedColumnName="id", nullable=true) 
    */ 
    private $offer; 

    /** 
    * @var \DateTime 
    * 
    * @Gedmo\Timestampable(on="create") 
    * @ORM\Column(name="createdAt", type="datetime") 
    */ 
    private $createdAt; 

    /** 
    * @var \DateTime 
    * 
    * @Gedmo\Timestampable(on="update") 
    * @ORM\Column(name="updatedAt", type="datetime") 
    */ 
    private $updatedAt; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="x", type="integer") 
    */ 
    protected $x = 0; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="y", type="integer") 
    */ 
    protected $y = 0; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="w", type="integer") 
    */ 
    protected $w = 0; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="h", type="integer") 
    */ 
    protected $h = 0; 

    /** 
    * @var boolean 
    * 
    * @ORM\Column(name="defaultImage", type="boolean") 
    */ 
    private $default = 0; 


    public function __construct() { 
     $this->position = 0; 
     $this->default = 0; 
     $this->x = 0; 
     $this->y = 0; 
    } 
    /** 
    * @ORM\PrePersist() 
    * @ORM\PreUpdate() 
    */ 
    public function preUpload() 
    { 
     $this->position = $this->position ?: 0; 
     $this->default = $this->default ?: 0; 
     $this->x = $this->x ?: 0; 
     $this->y = $this->y ?: 0; 

     /*if (null !== $this->getFile()) { 
      // do whatever you want to generate a unique name 
      $this->name = sha1(uniqid(mt_rand(), true)); 
      $this->originName = $this->getFile()->getClientOriginalName(); 
      $this->extension = $this->getFile()->guessExtension(); 

      $this->path = $this->name.'.'.$this->extension; 
     }*/ 
    } 

    /** 
    * @ORM\PreRemove() 
    */ 
    public function removeUpload() 
    { 

     echo $this->getRootPath().$this->originalImage; echo '<br/>'; 
     echo $this->getRootPath().$this->thumbnail; echo '<br/>'; 
     echo $this->getRootPath().$this->path; echo '<br/>'; 
     echo '<br/><br/>'; 

     if(file_exists($this->getRootPath().$this->originalImage)) 
      unlink($this->getRootPath().$this->originalImage); 
     if(file_exists($this->getRootPath().$this->thumbnail)) 
      unlink($this->getRootPath().$this->thumbnail); 
     if(file_exists($this->getRootPath().$this->path)) 
      unlink($this->getRootPath().$this->path); 
    } 
    /** other stuff */ 
} 

ответ

2

Ваших сущностей ссылающихся друг друг, так что вы должны попытаться удалить их:

$offer->setLargeImage(null); 
$offer->setMediumImage(null); 
$offer->setSmallImage(null); 

и вызов flush() 1 раз до $em->remove($offer); и один раз после.

foreach ($offer->getGallery() as $image) { 
    $offer->removeGallery($image); 
} 
$em->flush(); 

$em->remove($offer); 
$em->flush(); 

Это будет работать только, если все изображения «в частной собственности», что означает, что они не ссылаются несколько раз в этой организации или другому юридическому лицу.

+0

Спасибо, что работает отлично! Но у меня есть один вопрос. Почему я должен использовать флеш два раза? – psalkowski

+0

Вы не можете удалить оба за один раз, потому что они ссылаются друг на друга. Есть внешние ключи с обеих сторон. Сначала вам нужно установить внешние ключи с одной стороны в NULL, а затем вы можете удалить остальные. – jchampion

0
$offer->setLargeImage(null); 
    $offer->setMediumImage(null); 
    $offer->setSmallImage(null); 

Ваш "$ предложение" не имеют когда вы удаляете его.

UPDATE

Когда вы делаете ваш 'найти() вы не имеете объект изображения, но прокси из-за отложенной загрузки. Если вам нужно предложение с объектами изображения, создайте запрос с помощью leftJoin на изображениях, чтобы получить изображения AND AND. И тогда я думаю, что у вас не будет проблем.

(смотрите в конце этого урока, чтобы пример LeftJoin на объектах:)

+0

Да, но если я прокомментировал эту строку, у меня есть такая ошибка SQL: SQLSTATE [23000]: Нарушение ограничения целостности: 1451 Не удается удалить или обновить родительскую строку: сбой ограничения внешнего ключа ('cms-symfony'. 'to_images', CONSTRAINT' FK_C6CDB2F753C674EE' FOREIGN KEY ('offer_id') ССЫЛКИ' to_offer' ('id')) От http://docs.doctrine-project.org/en/2.0.x/reference/working- with-association.html # orphan-removal мы можем узнать, как удалить объект, но это не работает для меня. – psalkowski

+0

Я обновил свой ответ – Peekmo

+0

Левое соединение не работает. У меня такая же проблема, как и раньше. – psalkowski

Смежные вопросы