Doctrine2 / 将元素从一个集合移动到另一个
Doctrine2 / Move element from a Collection to another
我有 3 个实体:Invoice
、Service
和 Line
Invoice
包含 Service
的集合
Service
包含 Line
的集合
我想将一个 Line
从 Service
集合移动到另一个 Service
集合,但是刷新时,我尝试移动的 Line
元素已从中删除数据库 ...
没有 persist / flush 的单元测试是可以的
用法示例:
if ($transferService)
{
$line->transferToService($service1, $service2);
}
else
{
$line->setService($service2);
}
发票:
class Invoice
{
/**
* @ORM\OneToMany(targetEntity="Service", mappedBy="invoice", cascade={"persist", "merge", "remove"}, orphanRemoval=true)
*/
protected $services;
// ...
public function __construct()
{
$this->services = new ArrayCollection();
}
#################################################
# SERVICES Array Collection handling #
#################################################
public function getServices()
{
return $this->services;
}
public function setServices($services)
{
$this->services = new ArrayCollection();
return $this->addServices($services);
}
public function addService(Service $service)
{
if (!$this->services->contains($service))
{
$this->services->add($service);
$service->setInvoice($this);
}
return $this;
}
public function addServices($services)
{
foreach ($services as $service)
{
$this->addService($service);
}
return $this;
}
public function removeService(Service $service)
{
if ($this->services->contains($service))
{
$this->services->removeElement($service);
}
return $this;
}
public function removeServices($services)
{
foreach ($services as $service)
{
$this->removeService($service);
}
return $this;
}
// ...
}
服务:
class Service
{
/**
* @ORM\OneToMany(targetEntity="Line", mappedBy="service", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
*/
protected $lines;
/**
* @ORM\ManyToOne(targetEntity="Invoice", inversedBy="services", cascade={"persist", "merge"})
* @ORM\JoinColumn(name="invoice_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $invoice;
// ...
public function __construct()
{
$this->lines = new ArrayCollection();
}
public function getInvoice()
{
return $this->invoice;
}
public function setInvoice(Invoice $invoice)
{
$this->invoice = $invoice;
$invoice->addService($this);
return $this;
}
#################################################
# LINES Array Collection handling #
#################################################
public function setLines($lines)
{
$this->lines = new ArrayCollection();
return $this->addLines($lines);
}
public function getLines()
{
return $this->lines;
}
public function addLine(Line $line)
{
if (!$this->lines->contains($line))
{
$this->lines->add($line);
$line->setService($this);
}
return $this;
}
public function addLines($lines)
{
foreach ($lines as $line)
{
$this->addLine($line);
}
return $this;
}
public function removeLine(Line $line)
{
if ($this->lines->contains($line))
{
$this->lines->removeElement($line);
}
return $this;
}
public function removeLines($lines)
{
foreach ($lines as $line)
{
$this->removeLine($line);
}
return $this;
}
// ...
}
行:
class Line
{
/**
* @ORM\ManyToOne(targetEntity="Service", inversedBy="lines", cascade={"persist", "merge"})
* @ORM\JoinColumn(name="service_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $service;
public function setService(Service $service)
{
$this->service = $service;
$service->addLine($this);
return $this;
}
public function transferToService(Service $serviceFrom, Service $serviceTo)
{
$this->setService($serviceTo);
$serviceFrom->removeLine($this);
return $this;
}
public function getService()
{
return $this->service;
}
// ...
}
这是由于 orphanRemoval={true}
。这意味着集合对象 私有 仅由 "original" 所有者拥有(例如:Line
)。
see here
您的代码似乎运行良好,除非 - 也许您没有注意到 - 原始元素已经消失但它们也使用不同的 ID 重新创建。这种情况我不止一次遇到过,请检查一下。
因此,如果您想保留同一个对象,您应该删除 orphanRemoval
并手动处理集合生命周期(包括删除;我敢打赌您使用它来编写尽可能少的代码在表单集合和嵌入表单中)
我有 3 个实体:Invoice
、Service
和 Line
Invoice
包含Service
的集合
Service
包含Line
的集合
我想将一个 Line
从 Service
集合移动到另一个 Service
集合,但是刷新时,我尝试移动的 Line
元素已从中删除数据库 ...
没有 persist / flush 的单元测试是可以的
用法示例:
if ($transferService)
{
$line->transferToService($service1, $service2);
}
else
{
$line->setService($service2);
}
发票:
class Invoice
{
/**
* @ORM\OneToMany(targetEntity="Service", mappedBy="invoice", cascade={"persist", "merge", "remove"}, orphanRemoval=true)
*/
protected $services;
// ...
public function __construct()
{
$this->services = new ArrayCollection();
}
#################################################
# SERVICES Array Collection handling #
#################################################
public function getServices()
{
return $this->services;
}
public function setServices($services)
{
$this->services = new ArrayCollection();
return $this->addServices($services);
}
public function addService(Service $service)
{
if (!$this->services->contains($service))
{
$this->services->add($service);
$service->setInvoice($this);
}
return $this;
}
public function addServices($services)
{
foreach ($services as $service)
{
$this->addService($service);
}
return $this;
}
public function removeService(Service $service)
{
if ($this->services->contains($service))
{
$this->services->removeElement($service);
}
return $this;
}
public function removeServices($services)
{
foreach ($services as $service)
{
$this->removeService($service);
}
return $this;
}
// ...
}
服务:
class Service
{
/**
* @ORM\OneToMany(targetEntity="Line", mappedBy="service", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
*/
protected $lines;
/**
* @ORM\ManyToOne(targetEntity="Invoice", inversedBy="services", cascade={"persist", "merge"})
* @ORM\JoinColumn(name="invoice_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $invoice;
// ...
public function __construct()
{
$this->lines = new ArrayCollection();
}
public function getInvoice()
{
return $this->invoice;
}
public function setInvoice(Invoice $invoice)
{
$this->invoice = $invoice;
$invoice->addService($this);
return $this;
}
#################################################
# LINES Array Collection handling #
#################################################
public function setLines($lines)
{
$this->lines = new ArrayCollection();
return $this->addLines($lines);
}
public function getLines()
{
return $this->lines;
}
public function addLine(Line $line)
{
if (!$this->lines->contains($line))
{
$this->lines->add($line);
$line->setService($this);
}
return $this;
}
public function addLines($lines)
{
foreach ($lines as $line)
{
$this->addLine($line);
}
return $this;
}
public function removeLine(Line $line)
{
if ($this->lines->contains($line))
{
$this->lines->removeElement($line);
}
return $this;
}
public function removeLines($lines)
{
foreach ($lines as $line)
{
$this->removeLine($line);
}
return $this;
}
// ...
}
行:
class Line
{
/**
* @ORM\ManyToOne(targetEntity="Service", inversedBy="lines", cascade={"persist", "merge"})
* @ORM\JoinColumn(name="service_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $service;
public function setService(Service $service)
{
$this->service = $service;
$service->addLine($this);
return $this;
}
public function transferToService(Service $serviceFrom, Service $serviceTo)
{
$this->setService($serviceTo);
$serviceFrom->removeLine($this);
return $this;
}
public function getService()
{
return $this->service;
}
// ...
}
这是由于 orphanRemoval={true}
。这意味着集合对象 私有 仅由 "original" 所有者拥有(例如:Line
)。
see here
您的代码似乎运行良好,除非 - 也许您没有注意到 - 原始元素已经消失但它们也使用不同的 ID 重新创建。这种情况我不止一次遇到过,请检查一下。
因此,如果您想保留同一个对象,您应该删除 orphanRemoval
并手动处理集合生命周期(包括删除;我敢打赌您使用它来编写尽可能少的代码在表单集合和嵌入表单中)