0

如何從沒有級聯選項的反向MTO關係端刪除欠方? ,如何更新沒有級聯選項的關係的反面?如何從沒有級聯選項的反向MTO關係端刪除欠缺?如何更新關係的反向端?

錯誤是,如果我更改房間(MTO)的地址(OTM),房間仍然保留在先前的地址中,但我將其刪除。

if($this->addrOTM_b_ -> getRoomMTO_b_1() -> contains($this)) { 
    $this->addrOTM_b_ -> getRoomMTO_b_1() -> remove($this); 
} 

如果我檢查房間的地址 - 這是正確的新地址。 但是,如果我檢查地址中的房間,他們是錯誤的,因爲存在的房間已被刪除。

也許有一個命令我如何刷新實體?或者我將如何從地址中刪除房間?或者,也許不可能在實體層面做出決定,我會在控制器層面採取行動?

這個職位有COMENT,這是不可能的:Doctrine: can't removeElement from inverse side of the relation

這只是雙向MTO關係的例證, 一般而言,這是很難的房間轉移到另一個地址,除非它是一個船/帳篷/麪包車。

p.s. 我知道在foreach循環中刷新並不好,但是我不能清除實體管理器,因爲我將在第二個循環中使用實體。 無論如何,這些循環是litte,thre只有5個地址和20個房間。

//控制器動作,那種夾具

//FIRST ROUND seeting random address for each room 
    foreach ($roomEntArr as $roomEnt) { 
     $addrCnt = count($addrEntArr)-1; 
     $i = rand(0, $addrCnt); 
     $addrEnt = $addrEntArr[$i]; 
     $roomEnt->setAddrOTM_b_($addrEnt); 
     $this->em->persist($roomEnt); 
     $this->em->persist($addrEnt); 
     $this->em->flush(); 
    } 

    $addrRoomArr1 = []; 
    foreach ($addrEntArr as $ent1) {  
     $addrId = $ent1->getId(); 
     $roomEnts = $ent1->getRoomMTO_b_1(); $roomStr=""; 
     if(!empty($roomEnts)) { 
      foreach ($roomEnts as $addr) { $roomStr .= $addr->getId().','; } 
     } 
     $addrRoomArr1[$addrId] = $roomStr; 
    } //foreach ($ent1arr as $ent1) { 

    $roomAddrArr1 = []; 
    if($dir==='b') { 
     foreach ($roomEntArr as $ent2) { 
      $roomId = $ent2->getId(); 
      $addr = $ent2->getAddrOTM_b_(); $addrStr=""; 
      if($addr !== null) { $addrStr = $addr->getId().','; } 
      $roomAddrArr1[$roomId] = $addrStr; 
     } //foreach ($ent1arr as $ent1) { 
    } //if($dir==='b') { 

    //SECOND ROUND seeting random address for each room 
    foreach ($roomEntArr as $roomEnt) { 
     $addrCnt = count($addrEntArr)-1; 
     $i = rand(0, $addrCnt); 
     $addrEnt = $addrEntArr[$i]; 
     $roomEnt->setAddrOTM_b_($addrEnt); 
     $this->em->persist($roomEnt); 
     $this->em->persist($addrEnt); 
     $this->em->flush(); 
    } 

    $addrRoomArr1 = []; 
    foreach ($addrEntArr as $ent1) {  
     $addrId = $ent1->getId(); 
     $roomEnts = $ent1->getRoomMTO_b_1(); $roomStr=""; 
     if(!empty($roomEnts)) { 
      foreach ($roomEnts as $addr) { $roomStr .= $addr->getId().','; } 
     } 
     $addrRoomArr1[$addrId] = $roomStr; 
    } //foreach ($ent1arr as $ent1) { 

    $roomAddrArr1 = []; 
    if($dir==='b') { 
     foreach ($roomEntArr as $ent2) { 
      $roomId = $ent2->getId(); 
      $addr = $ent2->getAddrOTM_b_(); $addrStr=""; 
      if($addr !== null) { $addrStr = $addr->getId().','; } 
      $roomAddrArr1[$roomId] = $addrStr; 
     } //foreach ($ent1arr as $ent1) { 
    } //if($dir==='b') { 

//間實體

<?php 

namespace DctrBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping\Entity; 
use Doctrine\ORM\Mapping\Table; 
use Doctrine\ORM\Mapping\Index; 
use Doctrine\ORM\Mapping\Id; 
use Doctrine\ORM\Mapping\GeneratedValue; 
use Doctrine\ORM\Mapping\Column; 
use Doctrine\ORM\Mapping\OneToOne; 
use Doctrine\ORM\Mapping\OneToMany; 
use Doctrine\ORM\Mapping\ManyToOne; 
use Doctrine\ORM\Mapping\ManyToMany; 
use DctrBundle\Entity\AddrOTM_b_; 


/** 
/** 
* @Table(name="t_roomMTO_b_1") 
* @Entity(repositoryClass="DctrBundle\Repository\RoomMTO_b_1Repository") 
*/ 
class RoomMTO_b_1 { 

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

/** 
* @ManyToOne(targetEntity="DctrBundle\Entity\AddrOTM_b_", inversedBy="roomMTO_b_1") 
* @JoinColumn(name="addr_id", referencedColumnName="id") 
*/ 
    private $addrOTM_b_; 


    public function __construct() { 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    }      


    /** 
    * Get AddrOTM_b_ 
    * 
    * @return DctrBundle\Entity\AddrOTM_b_ 
    */ 
    public function getAddrOTM_b_() 
    { 
     return $this->addrOTM_b_; 
    } 

    /** 
    * Get AddrOTM_b_ 
    * 
    * @return DctrBundle\Entity\AddrOTM_b_ 
    */ 
    public function setAddrOTM_b_($addrOTM_b_) 
    { 
     if ($addrOTM_b_ !== null) { 

//if current address is not null, and if it is not the same 
//1) remove the room from the previous address if it exists 
//2) set new address to this room (automatically removes the oldAddress from the room) 
      if ($this->addrOTM_b_ !== null) { 

       if($addrOTM_b_->getId() != $this->addrOTM_b_->getId()) { 

        // first you have to remove this room from previous address - this part does not work, according docs : Changes made only to the inverse side of an association are ignored. Make sure to update both sides of a bidirectional association (or at least the owning side, from Doctrine’s point of view). http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html 
        if($this->addrOTM_b_ -> getRoomMTO_b_1() -> contains($this)) { 
         $this->addrOTM_b_ -> getRoomMTO_b_1() -> remove($this); 
        } 
        // then you can set the room to the new address 
        $this->addrOTM_b_ = $addrOTM_b_; 
       } // if($addrOTM_b_->getId() != $this->addrOTM_b_->getId) { 

      } // if ($this->addrOTM_b_ !== null) { 
      else { 
       //if current address is null, just set the address 
       $this->addrOTM_b_ = $addrOTM_b_; 
      } 

      //3) add room to the new address 
      if (!$addrOTM_b_->hasRoomMTO_b_1($this)) { 
       //$addrMTM_b_1->getRoomMTM_b_()->removeElement($this); 
       $addrOTM_b_->addRoomMTO_b_1($this); 
      } 
      return $this; 
     } // if ($addrOTM_b_ !== null) { 

     else { 
      if ($this->addrOTM_b_ !== null) { 
       $idold = $this->addrOTM_b_->getId(); 
       //remove this room from previous address 
       if($this->addrOTM_b_ -> getRoomMTO_b_1() -> contains($this)) { 
        $this->addrOTM_b_ ->getRoomMTO_b_1()->remove($this); 
       } 
       $this->addrOTM_b_ = null; 
      } // if ($this->addrOTM_b_ !== null) { 
      return true; 
     } // else of if ($addrOTM_b_ !== null) {    

    } //public function setAddrOTM_b_($addrOTM_b_) 

    /** 
    * @param DctrBundle\Entity\RoomMTO_b_1 $AddrOTM_b_ 
    * @return bool 
    */ 
    public function hasAddrOTM_b_($addrOTM_b_) 
    { 
     if(($addrOTM_b_!==null) && ($this->addrOTM_b_!== null)) { 
      return ($addrOTM_b_->getId() == $this->getAddrOTM_b_()->getId()); 
     } 
     else { 
      return false; 
     } 
    } 



    /** 
    * Return Entity as string 
    * 
    * @return string String representation of this class 
    */ 
    public function __toString() 
    { 
     return strval($this->id); 
    } 

} // class RoomMTO_b_1 { 

//地址實體

<?php 

namespace DctrBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping\Entity; 
use Doctrine\ORM\Mapping\Table; 
use Doctrine\ORM\Mapping\Index; 
use Doctrine\ORM\Mapping\Id; 
use Doctrine\ORM\Mapping\GeneratedValue; 
use Doctrine\ORM\Mapping\Column; 
use Doctrine\ORM\Mapping\OneToOne; 
use Doctrine\ORM\Mapping\OneToMany; 
use Doctrine\ORM\Mapping\ManyToOne; 
use Doctrine\ORM\Mapping\ManyToMany; 
use DctrBundle\Entity\RoomMTO_b_1; 


/** 
/** 
* @Table(name="t_addrOTM_b_") 
* @Entity(repositoryClass="DctrBundle\Repository\AddrOTM_b_Repository") 
*/ 
class AddrOTM_b_ { 

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

/** 
* @OneToMany(targetEntity="DctrBundle\Entity\RoomMTO_b_1", mappedBy="addrOTM_b_") 
*/ 
    private $roomMTO_b_1; 


    public function __construct() { 
     $this->roomMTO_b_1 = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    }      

    /** 
    * Get RoomMTO_b_1 
    * 
    * @return DctrBundle\Entity\RoomMTO_b_1 
    */ 
    public function getRoomMTO_b_1() 
    { 
     return $this->roomMTO_b_1; 
    } 

    /** 
    * Remove RoomMTO_b_1 
    * 
    * @param DctrBundle\Entity\AddrOTM_b_ $RoomMTO_b_1 
    */ 
    public function removeRoomMTO_b_1 (\DctrBundle\Entity\RoomMTO_b_1 $roomMTO_b_1) 
    { 

     if($roomMTO_b_1->getAddrOTM_b_()->getId() == $this->id) { 
      $roomMTO_b_1->setAddrOTM_b_(null); 
     } // 

     if ($this->hasRoomMTO_b_1($roomMTO_b_1)) { 
      $this->roomMTO_b_1->removeElement($roomMTO_b_1); 
     } // else if (!$this->hasRoomMTO_b_1($roomMTO_b_1)) 

    } //remove 


    /** 
    * Add RoomMTO_b_1 
    * 
    * @param DctrBundle\Entity\AddrOTM_b_ $RoomMTO_b_1 
    * 
    * @return RoomMTO_b_1 
    */ 
    public function addRoomMTO_b_1(\DctrBundle\Entity\RoomMTO_b_1 $roomMTO_b_1) 
    { 
     if(!$roomMTO_b_1 instanceof \DctrBundle\Entity\RoomMTO_b_1) { 
      throw new \InvalidArgumentException('$roomMTO_b_1 must be null or instance of DctrBundle\Entity\RoomMTO_b_1'); 
     } 
     else if (!$this->hasRoomMTO_b_1($roomMTO_b_1)) { 

      $this->roomMTO_b_1->add($roomMTO_b_1); 
      //echo "<br> 150,addRoomMTO_b_1 setting room to address in ".__FILE__; 

      if (!$roomMTO_b_1->hasAddrOTM_b_($this)) { 
       $roomMTO_b_1->setAddrOTM_b_($this); 
      }  

     } // else if (!$this->hasRoomMTO_b_1($RoomMTO_b_1)) { 

     return $this;   

    } // 

    /** 
    * @param DctrBundle\Entity\AddrOTM_b_ $RoomMTO_b_1 
    * @return bool 
    */ 
    public function hasRoomMTO_b_1($roomMTO_b_1) 
    { 
     return $this->getRoomMTO_b_1()->contains($roomMTO_b_1); 
    } 



    /** 
    * Return Entity as string 
    * 
    * @return string String representation of this class 
    */ 
    public function __toString() 
    { 
     return strval($this->id); 
    }    

} //class AddrOTM_b_ { 

回答

0

的原因是錯誤的語法,錯誤的 - remove ,RIGHT - removeElement

房內實體WRONG setAddrOTM_b _($地址):

if($this->addrOTM_b_ -> getRoomMTO_b_1() -> contains($this)) { 
    $this->addrOTM_b_ -> getRoomMTO_b_1() -> remove($this); 
} 

房內實體RIGHT setAddrOTM_b _($地址):

if($this->addrOTM_b_ -> getRoomMTO_b_1() -> contains($this)) { 
    $this->addrOTM_b_ -> getRoomMTO_b_1() -> removeElement($this); 
}