如何從沒有級聯選項的反向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_ {