你在这里做的事情被打破了:
SELECT
u, p
FROM
User u
JOIN
u.posts p
WITH
p.isFlagged = true
这将使用错误的值对“User#posts”集合进行水合,从而导致逻辑损坏、对象图损坏、一切都损坏。
您应该在 DQL 级别使用以下方法解决此问题:
SELECT
u, p
FROM
User u
JOIN
u.posts p
JOIN
u.posts j
WITH
j.isFlagged = true
这将基本上水合用户对象中正确的帖子集合,而没有任何中间(损坏)状态。
编辑:我误解了这个问题,因为我的想法是基于@Athlan 的回答,这从根本上是错误的(刷新损坏的集合真的是错误的)。这是我之前的答案,我仍然认为它很有趣,因为它解决了问题,但不是以真正正确的方式。
这个问题实际上让我很好奇 ORM 是否像我预期的那样刷新了集合。
我在这个分支中编写了测试。
基本上,您需要做的只是:
$entityManager->refresh($entity);
这是测试的相关部分:
$foo = new DDC2666Foo();
$this->_em->persist($foo);
$this->_em->flush();
$this->_em->clear();
$fetchedFoo = $this->_em->find(__NAMESPACE__ . '\DDC2666Foo', $foo->id);
$fetchedFoo->bars->add(new DDC2666Bar());
$this->assertCount(1, $fetchedFoo->bars);
$this->_em->refresh($fetchedFoo);
$this->assertCount(0, $fetchedFoo->bars, 'The collection was reset');
唯一的缺点是这也会重新获取您的实体,但 ORM 本身不提供刷新单个集合的外观。
无论如何,这也是一件好事,因为这样,您不会破坏封装,这可能会导致代码中出现意外(且难以调试)行为。