DQL JOIN关联后User实体的metadata属性未填充问题排查
首先可以明确:该问题和User不是关联的owning side没有任何关系,owning side的规则仅影响关联关系的持久化更新,不关联查询过程中的数据加载。
你遇到的metadata属性为空的核心原因有两个:
- DQL未配置关联预加载
你当前的DQL仅写了SELECT user,JOIN user.metadata metadata只是做了内连接过滤,用于筛选出至少有一条metadata记录的用户,并不会把关联的metadata数据同步加载到User实例的metadata属性中。你要预加载该关联集合,需要把metadata也加到SELECT子句中:
$dql = " SELECT user, metadata FROM \meQ\Entity\User user JOIN user.profile profile JOIN profile.client client JOIN user.metadata metadata WHERE user.uid = :user_id ";
修改后执行查询,metadata属性就会直接填充对应记录。
至于你看到user->profile、user->profile->client已填充,是因为这两个是toOne类型的关联,要么是fetch策略配置为EAGER自动加载,要么是dump时触发了代理对象的初始化逻辑,和关联类型的默认加载规则有关。
- EXTRA_LAZY加载策略的影响
你在User的metadata关联上配置了fetch: EXTRA_LAZY,这种策略下集合的初始化触发条件非常严格,仅当你实际访问集合内的元素时才会触发懒加载,dump操作不会触发加载,所以你看到的是未初始化的空ArrayCollection,不是真的没有数据,你只要调用$user->getMetadata()的相关方法(比如count()、first())就会自动触发查询加载对应18条记录。
如果你不需要每次都预加载metadata,也可以不用修改DQL,业务代码用到该关联时Doctrine会自动触发懒加载查询数据。
内容的提问来源于stack exchange,提问作者amacrobert
相关产品推荐
相关产品推荐

