[英]Symfony2 and Doctrine: how to fetch two different object for the same id?
我有这种情况:
等等。
在我的代码中,我需要为tmp原因制作一个对象(比如A)的“副本”(不,我不能使用不同的结构,我需要有一个对象的副本)。
如果我使用clone
,显然,我复制了我的对象但是与他相关的对象没有被克隆。
我完全知道我可以覆盖魔术方法__clone()
,以便从A对象的角度来分配__clone()
,C,D作为对象本身的克隆,但是我有很多对象(并且包含很多对象)为了Doctrine目的而进入ArrayCollection
)我宁愿避免覆盖每个对象的clone函数。
或者,我认为我可以通过这种方式从教条中重新获取一个对象来创建一个新对象:
$aCopy = $this->entity_manager
->getRepository('MyBundle:A')
->find($a->getId());
其中$a
是class A
的实例
执行此操作后 - 当然这是“错误的”,因为我怀疑doctrine会将该对象标记为“alredy fetched”并返回其指针( )* - 我只需使用spl_object_hash()
函数打印我的两个对象的ID,当然,它们引用相同的对象ID,因此对同一个对象。
我不能使用doctrine detach()
函数,因为我需要在此操作后使原始对象可用
我该如何解决这种情况? 正如你所看到的,我尝试了两种不同的方式,但没有一种方式让我感到满意。
我也标记了php,因为如果有人能指出我不同的解决方案,基于php-pure,我也会考虑到它
(*)
在这种情况下,文章可以从实体管理器访问两次,但在两者之间进行修改。 Doctrine 2实现了这一点,并且只会让您访问ID为1234的文章的一个实例,无论您多久从EntityManager中检索它,甚至无论您使用何种查询方法(find,Repository Finder或DQL)。 这称为“身份映射”模式,这意味着Doctrine会保留每个实体的映射以及每个PHP请求检索到的ID,并不断返回相同的实例。
这证实了我之前说过的话
答案没有我想象的那么复杂。
它似乎足以调用$this->entity_manager->clear();
这将清除此实体地图并强制它从数据库重新加载到一个全新的对象!
$this->entity_manager->clear();
$aCopy = $this->entity_manager
->getRepository('MyBundle:A')
->find($a->getId());
$this->logger->debug('Original Obj: '.spl_object_hash($a));
$this->logger->debug('Copied Obj: '.spl_object_hash($aCopy));
这将打印
[2013-02-08 12:07:20] app.DEBUG:Original Obj:000000006523 645c 000000004b1160d1 [] [] [2013-02-08 12:07:20] app.DEBUG:Copied Obj:000000006523 66e3 000000004b1160d1 [] []
据我所知,这不是开箱即用的支持D2行为,所以我想你需要自己实现克隆操作。
话虽如此,我也不是100%肯定如果序列化然后反序列化D2实体会发生什么,这可能会做你想要的(虽然是一种相当不愉快的方式)。 此外,您可以在最初获取实体后,立即分离您收到的内容并在对“实时”副本的任何引用传播到原始实例化点之外之前再次重新获取结果(如果查询使用结果缓存这不应该带来太多的惩罚)。 据推测,这不会是一个巨大的问题,因为你只是临时处理副本。
WRT清算实体经理,它将分离所有管理实体,这可能会产生不良副作用。
HTH。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.