【问题标题】:JPA: why lazy fields are loaded if EntityManager is closedJPA:如果 EntityManager 关闭,为什么会加载惰性字段
【发布时间】:2016-06-10 05:59:51
【问题描述】:

我使用eclipselink,代码如下:

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() 处得到异常。

编辑 1 经过一些研究,我发现了以下内容 - 我上面描述的行为是静态编织时的实际行为(&lt;property name="eclipselink.weaving" value="static"/&gt; + de.empulse.eclipselink 编织插件)。但是,当编织是动态的 (&lt;property name="eclipselink.weaving" value="true"/&gt;) 我得到异常:

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

【问题讨论】:

标签: java jpa eclipselink


【解决方案1】:

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

this email chain discussing the "feature"。它没有提到关闭它的方法(这样你就可以拥有便携的行为),实际上是要求这个人请求它!关于为什么 JPA TCK 不检查可移植行为的问题是向 Oracle 提出的一个问题……但是等等,EclipseLink 团队编写了 TCK,不是他们……嗯……

为了保持便携性,您将按照 JPA 规范进行分离,而不是依赖此类行为

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    相关资源
    最近更新 更多