我正在尝试使用供应商制作的自定义Doctrine类型。供应商使用此类型,效果很好。但是我在使用它时遇到了问题。类型为JMSPaymentCoreBundle's ExtendedData
。我在以下实体中使用它:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Payment\CoreBundle\Entity\ExtendedData;
/**
* Class Customer
*
* @package AppBundle\Entity
* @ORM\Entity
* @ORM\Table(name="customers")
* @ORM\HasLifecycleCallbacks()
* @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
*/
class Customer {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var \DateTime
*
* @ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;
/**
* @var ExtendedData
*
* @ORM\Column(name="extended_data", type="extended_payment_data")
*/
private $extendedData;
private $extendedDataOriginal;
public function __construct() {
$this->extendedData = new ExtendedData();
$this->extendedDataOriginal = clone $this->extendedData;
}
/**
* @ORM\PostLoad()
*/
public function onPostLoad() {
$this->extendedDataOriginal = clone $this->extendedData;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function onPreSave() {
$this->updatedAt = new \DateTime();
// this is necessary until Doctrine adds an interface for comparing
// value objects. Right now this is done by referential equality
if (null !== $this->extendedDataOriginal && false === $this->extendedData->equals($this->extendedDataOriginal)) {
$this->extendedData = clone $this->extendedData;
}
}
/**
* @return ExtendedData
*/
public function getExtendedData() {
return $this->extendedData;
}
/**
* @return int
*/
public function getId() {
return $this->id;
}
/**
* @return mixed
*/
public function getUpdatedAt() {
return $this->updatedAt;
}
}
回调和实体属性(如DEFERRED_EXPLICIT
更改跟踪政策)是从JMSPaymentCoreBundle here中存在的实体复制的。
我遇到的实际问题是Doctrine不会检测到对我的实体中的ExtendedData所做的任何更改。我有DEFERRED_EXPLICIT
作为更改跟踪策略,我明确地持有Customer实体但是(我推测)强制Doctrine查看extendedData
中的更改的回调没有被调用,因为实体不是随着教义没有变化,将继续坚持下去。通过执行$customerInstance->getExtendedData()->set('key', 'value')
等内容来完成更改。
我做了一些深入研究Doctrine的UnitOfWork
,我认为当从数据库加载实体时,originalEntityData
引用ExtendedData
实例,所以当我进行修改时一个控制器,originalEntityData
中的实例也发生了变化,因此在UnitOfWork::computeChangeSet
中,原始数据等于新数据,并且没有任何变化。我想如果我在我的实体中有一个虚拟列,我会在每个持久操作之前修改它,然后“强制”调用preSave回调,但我宁愿不会弄乱我的实体。
除了虚拟列之外,有没有办法使这项工作?