2013-09-02 1 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 
* 
* @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); 

과 전화 :

(http://symfony.com/fr/doc/current/cookbook/security/entity_provider.html#gerer-les-roles-via-la-base-de-donnees 객체에 leftjoin의 예를 가지고이 튜토리얼의 끝을보고) flush() 번 전에 $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을 사용하여 쿼리를 작성하여 오퍼 및 이미지를 가져 오십시오. 그리고 나서, 당신은 문제가 없을 것이라고 생각합니다.

+0

예,이 줄에 주석을 달았다면 다음과 같은 SQL 오류가 있습니다. SQLSTATE [23000] : 무결성 제약 조건 위반 : 1451 부모 행을 삭제하거나 업데이트 할 수 없습니다 : 외래 키 제약 조건이 실패했습니다 ('cms-symfony'). 'to_images', CONSTRAINT'FK_C6CDB2F753C674EE' 외래 키 ('offer_id') 참조'to_offer' ('id')) http://docs.doctrine-project.org/ko/2.0.x/reference/working- with-associations.html # orphan-removal 엔티티를 삭제하는 방법을 배울 수 있지만 나에게 적합하지 않습니다. – psalkowski

+0

대답을 업데이트했습니다 – Peekmo

+0

왼쪽으로 조인이 작동하지 않습니다. 나는 이전과 같은 문제가있다. – psalkowski