【问题标题】:Doctrine returns proxy object when joining table with nullable relations加入具有可为空关系的表时,Doctrine 返回代理对象
【发布时间】:2014-11-08 17:13:08
【问题描述】:

我正在尝试从一个与另一个类连接的类中检索实体。 并非所有实体实际上都加入了实体。

有点像下面的语句:

SELECT a, b FROM A a LEFT JOIN B b ON a.id = b.aid GROUP BY a.id;

或在代码中:

$query_builder = $em->getRepository('repository_of_A')->createQueryBuilder('a');
$query_builder = $query_builder->leftJoin('a.b', b);
$query_builder = $query_builder->groupBy('a.id');
$query = $query_builder->select('a, b')->getQuery();
$entities = $query->getResult();

现在的问题是,只要 A 没有实体 B,Doctrine 就会为 A 返回一个代理对象。 因为我使用反射,所以我需要真实对象而不是代理。

在随附的屏幕截图中,索引为 26 的对象没有对应于 A(商店)的实体 B。

有谁知道为什么以及如何解决这个问题?

注意:我知道在使用反射时我可以只使用类名而不是实体,但我也想了解这里的问题,因为它可能会影响运行时... p>

编辑:附上截图

【问题讨论】:

  • 看起来很奇怪。是否有更多的关联?无论如何,在使用 Doctrine 2 时,您需要能够处理代理。
  • 实际上还有很多关联,但是查询只要求 A 和 B。好吧,我现在使用 ClassUtils::getClass(...) 以确保反射仍然有效。但是,我仍然有兴趣解决这个问题..
  • 其他关联将导致创建代理以支持延迟加载。我所知道的唯一解决方法是让您进行某种数据转换或制作自己的 Doctrine 2 水合器。但最好的办法是让反射代码支持代理。
  • 先谢谢,但我还是不明白。其他关联可能是代理对象,但为什么我的主要实体是代理对象?我不关心其他关联,因为我只需要 A 的原始数据(以及连接实体 B 的原始数据)。因此,所有其他相关实体的代理都很好。正如我所说,我的代码甚至可以与使用 Doctrine 的 ClassUtils 的代理一起工作。
  • 这 A 和 B 的东西令人困惑。 A是你的主要实体吗?如果 A 有关联(即数组集合),则 A 将作为代理返回。有多种方法可以设置您的查询,以便您只获得所需的确切属性。但这通常意味着您无法更新并将更改持久化回您的数据库。

标签: php symfony join proxy doctrine


【解决方案1】:

如果问题是没有加载字段,那么在使用反射之前检查 Doctrine 是否加载了实体,否则加载它:

if (
    $object instanceof \Doctrine\Common\Persistence\Proxy
    && !$object->__isInitialized()
) {
    $object->__load();
}
// ... your code

但正如我从您的屏幕截图中看到的那样,您错误地识别了问题。如果您首先选择a(如您的示例),那么结果列表中将没有代理。

正如我猜想的那样,在您的示例中,所有 Shop 实体都处于某种关联中(不是通过查询选择的,但例如来自 $country->getShops();)并且 Shop [70] 不是代理,只是因为在那之前的某个地方 Doctrine 已经加载它。如果实体在地图中(按 ID) - 使用它而不是代理,因为它已经加载。

【讨论】:

  • 实际上,我使用 DQL 语句来让所有商店加入他们的 cmets,类似于上面描述的那个。屏幕截图显示了该查询给出的我的结果集。这就是我不理解代理对象的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 2016-07-04
  • 2018-11-25
  • 1970-01-01
  • 2013-01-06
相关资源
最近更新 更多