Jpa 日食延迟加载
我正在eclipselink JPA 2上运行一个测试,以确定集合的延迟加载是如何工作的。我假设,如果您加载一个实体,那么首先加载所有急切的元素,然后在JPA会话中,当您请求或触摸惰性元素时(以某种方式引用它们,比如获取惰性集合的大小)加载惰性元素。我的问题是:当我从会话中分离实体时,惰性集合被加载,并且是可用的,即使我没有要求它??我要么误解了JSR,要么这是eclipselink中的正常行为。通过使用hibernate,我知道这不会发生Jpa 日食延迟加载,jpa,eclipselink,Jpa,Eclipselink,我正在eclipselink JPA 2上运行一个测试,以确定集合的延迟加载是如何工作的。我假设,如果您加载一个实体,那么首先加载所有急切的元素,然后在JPA会话中,当您请求或触摸惰性元素时(以某种方式引用它们,比如获取惰性集合的大小)加载惰性元素。我的问题是:当我从会话中分离实体时,惰性集合被加载,并且是可用的,即使我没有要求它??我要么误解了JSR,要么这是eclipselink中的正常行为。通过使用hibernate,我知道这不会发生 EntityManager em = emf.crea
EntityManager em = emf.createEntityManager();
AloadTest at1 = em.find(AloadTest.class, pkLazy);
serializeObject(at1,"InSessionLazy");
em.detach(at1);
em.close();
如果我在调试中运行它,并观察我的惰性元素,我可以看到当我访问我的“at1”对象时它们没有被加载,但是当我跨过em.detach(at1)行时,惰性实体就被加载了
我在AloadTest C.D.中定义了一个惰性集合:
@OneToMany(fetch = javax.persistence.FetchType.LAZY, cascade = CascadeType.PERSIST, /*, cascade = CascadeType.ALL, */mappedBy = "aloadtest")
public Set<CloadLazyMultitest> getCloadLazyMultitest() {
return cloadLazyMultitest;
}
public void setCloadLazyMultitest(Set<CloadLazyMultitest> cloadLazyMultitest) {
this.cloadLazyMultitest = cloadLazyMultitest;
}
以及我的记录器的输出:
17:14:16.707 [main] INFO c.c.t.j.t.JpaI3EagerAndLazyLoadingTest - ARE WE LAZY LOADED BEFORE :false
17:14:16.723[main]INFO c.c.t.j.t.jpai3急切和懒散的加载测试-我们是否在之后懒散加载:true
我的意思是?为什么要加载惰性集合,我不要求集合,只要求父实体。如果我有一个由2个或10个集合组成的链,每个集合都被注释为一个惰性集合,会发生什么?我认为这将是一个相当大的开销。Hibernate以前从来没有出现过这个问题,但由于eclipselink现在是JPA参考,我必须基于此构建一个解决方案
当然,分离对象、使其“脏”、进行一些处理并重新连接到新会话是可以的。我在“长对话”环境中考虑的更多,可能是无状态会话bean和web前端 在查看最新的EclipseLink代码时,detach()似乎不会触发惰性集合。你是否应该在触发它时分离 一般来说,EclipseLink允许您在关闭EntityManger后访问惰性关系,因此即使您分离了对象,它仍然可以访问这些关系(除非您序列化它) 您可以使用
((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()
在detach()调用之前和之后检查此项
我不知道为什么要使用detach,这是一种非常罕见的方法,它基本上可以用于从持久性上下文中排除对象,以避免将其更改写入数据库。EclipseLink允许加载延迟关系,只要连接仍然可用,如下所述:
您确定不是调试器在背后调用集合的方法(例如,它的toString方法)吗?serializeObject方法做什么?serialize对象直接序列化我的对象,当我反序列化这个对象时,它不包含lazzy加载的集合,这是预期的。它不是调试器,因为我在代码中的分离对象上循环,然后加载集合。这种自动加载集合的行为发生在我通过调试器发送集合之前。您好,我正在独立的J2SE环境中使用detach方法,以评估eclipselink对于即将到来的项目的优点。我想我们将使用一个无状态会话bean来访问真实环境中的对象。我的老板给了我一个清单,我正在勾选它们,LazyLoad测试,说我应该获取会话,获取对象,分离对象,查询惰性集合,它应该会抛出一个错误。嗨,James,我做了你的间接测试,并编辑了原始问题。嗨,Chris,我阅读了链接,尽管您没有要求,但集合是惰性加载的,这似乎仍然很奇怪,即在分离点。您的实体是否实现了访问惰性关系的toString方法?这将导致在启用日志记录时触发它,通常不建议这样做。嗨,Chris,不,我不重写toString(),也不在测试用例之外的任何地方打印惰性集合的内容。只要连接可用,这是什么意思?
((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()