关于jpa:Eclipselink延迟加载

Eclipselink Lazy Loading

我正在eclipselink JPA 2上运行测试,以确定集合的延迟加载的工作方式。我假设,如果您加载一个实体,那么首先会加载所有渴望的元素,然后在JPA会话中,当您请求或触摸它们时会加载惰性元素(以某种方式引用它们,例如获取懒惰的收藏的大小)。我的问题是这样的:当我从会话中分离实体时,即使我没有要求,延迟集合也会被加载并且可用。我或者误解了JSR,或者这是eclipselink中的正常行为。通过使用hibernate模式,我知道这不会发生。

1
2
3
4
5
6
7
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中有一个已定义的惰性集合。像这样:...

1
2
3
4
5
6
7
@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;
    }

预先感谢,但是我认为如果我没有要求,我的懒惰收藏集就不会加载。

编辑:我对James进行了测试,您对间接测试是正确的:

1
2
3
4
5
logger.info(" ARE WE LAZY LOADED BEFORE :"+((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated());

        em.detach(at1);

        logger.info(" ARE WE LAZY LOADED AFTER :"+((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated());

输出到我的记录器:

1
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.JpaI3EagerAndLazyLoadingTest-在:true

之后我们是否延迟加载

我的意思是?为什么我要加载惰性集合,我不要求集合,仅是父实体。如果我有2个或10个集合的链,每个集合都标注为惰性集合,会发生什么情况?我认为这将是相当大的开销。 Hibernate以前从来都不是问题,但是由于eclipselink现在是JPA的引用,因此我必须基于此构建解决方案。

当然可以分离对象,使其变得"脏",进行一些处理并将其重新连接到新会话。我在"长期对话"环境中考虑更多问题,可能是无状态会话bean和Web前端?


在查看最新的EclipseLink代码时,似乎detach()不会触发惰性集合。您是否应该分离触发它?

通常,EclipseLink允许您在关闭EntityManger之后访问LAZY关系,因此,即使您分离了该对象,它仍然可以访问这些关系(除非您对其进行序列化)。

您可以使用

检查是否实例化了关系

1
((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()

在detach()调用之前和之后进行检查。

我不确定为什么要使用分离,这是一种非常罕见的方法,它基本上可以用于从持久性上下文中删除对象,以避免将其更改写入数据库。


EclipseLink允许在连接仍然可用时加载惰性关系,如此处所述:
http://forums.oracle.com/forums/thread.jspa?messageID=1706796