2016-06-10 53 views
4

我将EclipseLink,并具有以下代码:JPA:为什么懒惰场装载如果EntityManager的关闭

public Temp getTemp() { 
    EntityManager em=emf.createEntityManager(); 
    String queryString="SELECT a FROM Temp a"; 
    EntityGraph<Temp> eg = em.createEntityGraph(Temp.class); 
    eg.addAttributeNodes("id"); 
    //eg.addAttributeNodes("name"); 
    Query query = em.createQuery(queryString); 
    query.setHint("javax.persistence.fetchgraph", eg); 
    List<Temp> items=query.getResultList(); 
    em.close();// ENTITYMANAGER IS CLOSED 
    return items.get(0); 
} 

public void temp(){ 
    Temp temp=getTemp(); 
    System.out.println("id:"+temp.getId()); 
    System.out.println("name:"+temp.getName()); 
} 

正如你可以从代码中看到的,我们只加载ID。但是,当我们执行temp.getName()时,会再次执行SQL查询并加载必要的数据。为什么?我们确实关闭了实体经理。我期望得到temp.getName()的异常。

EDIT 1 一些研究,我发现了以下后 - 我如上所述是编织时的实际的行为是静态的(<property name="eclipselink.weaving" value="static"/> + de.empulse.eclipselink织造插件)。然而,当编织是动态的(<property name="eclipselink.weaving" value="true"/>)我得到异常:

java.lang.ClassNotFoundException: org.eclipse.persistence.internal.jpa.EntityManagerImpl not found by com.temp [57] 
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574) 
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79) 
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at com.temp.Temp._persistence_checkFetched(Temp2.java) 
    at com.temp.Temp._persistence_get_name(Temp2.java) 
    at com.temp.Temp.getName(Temp.java:44) 

所以问题搬到这里:Eclipselink: Difference between static and dynamic weaving

+1

可能重复的[JPA EntityManager.detach()仍然加载懒惰关系](http://stackoverflow.com/questions/37562870/jpa-entitymanager-分离仍然加载懒惰关系) –

回答

2

因为那是EclipseLink的,它支持领域的超脱加载...即东西是不是在JPA规范并且完全不可移植(即在其他实现中不受支持)。它的“分离”状态并不真正“分离”,并保持与EntityManagerFactory的联系。如果关闭EMF,那么它们会变成真正的“分离”。

请参阅this email chain discussing the "feature"。它没有提及关闭它的一种方式(所以你可以有便携式行为),并且实际上要求这个人请求它!关于为什么JPA TCK不检查便携式行为的问题是甲骨文所要求的......但是请继续关注,EclipseLink团队编写TCK并不是他们......嗯..

要留便携式,你会按照JPA规范分离,而不依赖于这种行为

+0

也许你知道 - 有没有办法让它“分离”而不关闭工厂,因为它不可能解决方案关闭工厂这样的目的? –

+0

请参阅编辑1 –