Symfony:使用日期时间字段克隆 object 并向克隆的 object 日期添加天数

Symfony: clone object with Datetime field and add days to cloned object dates

我有一个看似简单的问题,但经过几个小时 try-and-error 我只得到了错误的结果。

目标是复制 object ConventionHallReservation 的 OneToMany 关系,并为此预订添加一些天数。我得到的结果是,天数被添加到克隆的 objects 和原始的 objects 中,我希望原始的 objects 保持不变。

这是重要的代码:

/**
 * @ORM\Entity()
 */
class Convention
{
/**
 * @ORM\OneToMany(targetEntity="HallReservation", mappedBy="convention", cascade={"all"})
 */
private $hallReservation;

/**
 * Clone object
 *
 */
public function __clone()
{
    if ($this->id)
    {
        $this->id=null;
        $this->reference = null;
        $this->registrationDate = new \Datetime('now');

        foreach ($this->hallReservation as $hallR)
        {
            $clonedR = clone $hallR;
            $clonedR->setConvention($this);
            $newRDate = clone $hallR->getDate();
            $clonedR->setDate($newRDate);
            $this->hallReservation->add($clonedR);
        }
    }
}

/**
 * @ORM\Entity()
 */
class HallReservation
{
/**
 * @var \Date
 *
 * @ORM\Column(name="date", type="date")
 */
private $date;

/**
 * Clone object
 *
 */
public function __clone()
{
    if ($this->id)
    {
        $this->id=null;
        $clonedDate = clone $this->date;
        $this->date = $clonedDate;

}

控制器代码:

        $jumpInterval = $originalConventionBeginDate->diff($newDate);
        foreach ($newConvention->getHallReservation() as $newHallR)
        {
            $prevDate = clone $newHallR->getDate();
            $prevDate->add($jumpInterval);

            $newHallR->setDate($prevDate);
        }
        $em->persist($newConvention);
        $em->flush();

如您所见,我克隆了 datetime object everywhere 但仍然添加了原始的会议厅预订日期。

当您克隆 Convention 对象时,您不会将 hallReservation 属性 设置为新的 Collection。 Doctrine 中的 OneToMany 关系映射到 Collection 对象,因此当您克隆 Convention 对象时,您会在克隆对象中获得对原始 hallReservation 集合的引用。

您可以尝试这样的操作:

<?php

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity()
 */
class Convention
{
/**
 * @ORM\OneToMany(targetEntity="HallReservation", mappedBy="convention", cascade={"all"})
 */
private $hallReservation;

/**
 * Clone object
 *
 */
public function __clone()
{
    if ($this->id)
    {
        $this->id=null;
        $this->reference = null;
        $this->registrationDate = new \Datetime('now');
        $reservations = new ArrayCollection();

        foreach ($this->hallReservation as $hallR)
        {
            $clonedR = clone $hallR;
            $clonedR->setConvention($this);
            $newRDate = clone $hallR->getDate();
            $clonedR->setDate($newRDate);
            $reservations->add($clonedR);
        }

        $this->hallReservation = $reservations;
    }
}