Eclipselink延迟加载 [英] Eclipselink Lazy Loading

查看:194
本文介绍了Eclipselink延迟加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am running a test on eclipselink JPA 2, to determine how lazy loading of a collection is working. I have assumed, the if you load an entity, then all eager elements are loaded first of all, then, within the JPA session, the lazy elements are loaded when you ask for them, or touch them (refer to them in some way, like getting the size of a lazy collection). The problem I have is this: when I detach the entity from the session, the lazy collection is loaded, and is available, even though I didn't ask for it?? I either mis-understand the JSR, or this is normal behaviour in eclipselink. From using hibernate, I know this does not happen.

EntityManager em = emf.createEntityManager();
        AloadTest at1 = em.find(AloadTest.class, pkLazy);

        serializeObject(at1,"InSessionLazy");

        em.detach(at1);
        em.close();

如果我在调试中运行此程序,并观察我的惰性元素,则可以看到在访问我的"at1"对象时未加载它们,但是当我越过em.detach(at1)行的那一刻,该惰性元素就被加载了实体已加载.

If I run this in a debug, and watch my lazy elements, I can see they are not loaded when I access my 'at1' object, but the minute I step over the em.detach(at1) line, the lazy entities are loaded.

我的AloadTest C.D中有一个已定义的惰性集合.这样:...

I have a defined lazy collection in my AloadTest C.D. as such:...

@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;
    }

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

Thanks in advance, but I do not think my lazy collection should be loaded if I havent asked for it.

我对James进行了测试,而您对间接测试的看法是正确的:

I did your test James, and your are correct about the indirection test:

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()); 

然后输出到我的记录器:

And the output to my logger:

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

17:14:16.723 [main] INFO c.c.t.j.t.JpaI3EagerAndLazyLoadingTest - ARE WE LAZY LOADED AFTER :true

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

My point is? why am I getting lazy collections loaded, I dont ask for the collection, just the parent entity. What would happen if I had a chain of 2 or 10 collections, each annotated as a lazy collection? I think it would be quite an overhead. Its never been an issue before with Hibernate, but as eclipselink is now the JPA refernce, I have to build a solution based on this.

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

Surely its ok to detach an object, to make it 'dirty', do some processing and re-attach to a new session. I am thinking more in a 'long conversation' environment, probably stateless session beans and a web front?

推荐答案

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

In looking at the latest EclipseLink code, it doesn't seem like detach() will trigger the lazy collection. Are you should detach is triggering it?

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

In general EclipseLink allows you to access LAZY relationships after closing the EntityManger, so even though you detached the object, it will still have access to the relationships (unless you serialize it).

您可以使用以下方式检查该关系是否已实例化

You can check if the relationship is instantiated using,

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

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

Check this before and after the detach() call.

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

I'm not sure why you are using detach, it is a pretty rare method, it basically can be used to expel an object from the persistence context to avoid its changes being written to the database.

这篇关于Eclipselink延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆