JPA + EclipseLink - 使用已关闭的EntityManager进行延迟加载

时间:2015-09-21 11:42:41

标签: java jpa jdbc eclipselink lazy-loading

我在Java SE项目中使用EclipseLink作为JPA提供程序。我已正确配置编织以允许延迟加载。

与Hibernate(抛出LazyInitializationException)不同,EclipseLink可以获得LAZY关系的代理,即使使用封闭的EntityManager也是如此。要运行此查询,它将从池中获取新连接。

是否有某些设置会禁用或更改此功能的行为?在尝试访问卸载的属性时,我需要获取空值或异常,例如Hibernate。

示例:

List<Customer> customers = entityManager.createQuery("from Customer c", Customer.class).getResultList();
entityManager.close(); // Closing the EntityManager

for (Customer customer: customers) {
    customer.getAddress(); // Here EclipseLink executes a query to get the relationship.
}

感谢。

2 个答案:

答案 0 :(得分:2)

EclipseLink允许您访问惰性关系,即使EntityManager已关闭也是如此。此行为是特定于EclipseLink的,不是JPA规范的一部分。

当Connection已关闭时,您将获得所需的Exception。

但是,EclipseLink将未实例化的列表包装到IndirectList中。您可以通过编程方式检查List是否已实例化。

if(customers instanceof IndirectList) {
    boolean foo = ((IndirectList) customers).isInstantiated();
    // ... 
}

另见:

答案 1 :(得分:0)

模式&#34;视野中的jpa会话&#34;是你的朋友。基本上:在请求循环期间打开EntityManager(很早或根据要求),不要关闭应用程序代码(可以获取所有延迟元素)并在最后一个操作中自动关闭EM。

我有同样的问题。 我个人使用Wicket,替换

class MyWebRequestCycle extends RequestCycle {
... // extract from bigger project
protected void onEndRequest() {
        super.onEndRequest();
        if (em != null) {
            if (em instanceof MyEntityManager) {
                MyEntityManager em2 = (MyEntityManager) em;
                em2.original.close();
            } else
                em.close();
            em = null;
        }
}

}

MyEntityManager是早期阶段EntityManager打开的代理(几乎在Eclpse中生成)。并且&#39;如果&#39;以上是因为开始申请,这不是我们讨论的一部分。

在其他框架中以适当的方式。这取决于你。

答案有两条路径:完整的JEE容器(程序员代码无需打开或关闭EM)和servlet容器。我的答案是第二个。

备注:此模式中的单词 session 不是Web会话,也不是JPA引擎的意义输入参数中的Session。这只是单词;)