【发布时间】:2013-07-28 00:00:06
【问题描述】:
我见过几个类似的问题,有 0 个很好的答案。
这应该很简单。我正在使用 Java JPA,我想有时但不是一直加载子实体列表。不幸的是,当我说懒惰地获取它时,JPA 似乎并没有在听我说话。我已经 100% 确定我的代码中没有任何地方可以以任何方式访问 childEntities 属性。但是,所有子实体仍然会在我的 JPA.em().find(..) 调用后立即加载。这就是我声明与注解的关系的方式。
@Entity
@Table(name = "parentEntities")
public class ParentEntity implements Serializable {
....
@OneToMany(mappedBy = "entityPropertyName", fetch = FetchType.LAZY)
public List<ChildEntity> childEntities;
...
}
这就是我加载父实体的方式:
ParentEntity parentEntity = JPA.em().find(ParentEntity.class, id);
此外,我希望有时急切地获取这个集合,并能够动态地告诉 JPA 何时这样做。不过,这是第 2 步。第 1 步只是为了让它正常工作。
【问题讨论】:
-
您如何验证它是否已获取?是否可能设置了 orm.xml 或其他位置映射或实体侦听器来覆盖惰性设置或触发集合?您使用的是什么提供商?
-
在调试器中,我可以在 find 调用后立即看到列表已填充。我没有使用任何 XML 进行配置,只有注释。
-
现在我已经创建了一个非常臃肿和 hacky 的解决方案。我创建了两个父实体,一个带有子列表集合,一个没有。不幸的是,这种 hack(正如许多 hack 所做的那样)将污秽级联到我的其余代码中。
-
您使用的是什么提供者,并且该实体之前是否已加载,因此关系可能已经被获取?在找到后尝试 em.refresh 并查看关系未触发,并确保您的调试器没有触发列表 - 它们类型的列表以及触发它的方式可能是特定的
-
JPA 是一个规范,而 hibernate、EclipseLink 等实现了该规范。您正在使用一个实现,而使用哪一个很重要。除了尝试刷新之外,您无需更改任何内容。如果它有效,那么我们知道您的提供程序支持惰性,并且正在发生诸如正在预加载的实体之类的事情。
标签: jpa lazy-loading