什么时候可以在事务之外加载JPA延迟加载的ManyToOne关系?

时间:2015-01-24 19:53:35

标签: jpa jax-rs eclipselink lazy-loading jpa-2.1

我有一个JAX-RS资源类。它调用一个无状态EJB来加载一个实体(让我们称之为Parent)。

Parent与另一个实体(我们称之为@ManyToOne)之间存在Child关系,并且配置为具有LAZY的获取类型。

没有任何额外的事务注释出现在任何内容上,因此无状态EJB具有在必要时启动事务的默认行为,并在业务方法完成后提交事务。

在调试器中,我观察到EJB返回的Parent的{​​{1}}值为null,正如我怀疑的那样。因此,延迟加载工作正常。

我的资源类然后构建一个Child并将控制交给JAX-RS内部。同样,没有交易是开放的。

序列化后,显示的JSON(在我的例子中)包含Response的所有字段。 JAX-RS内部的某些东西在某种程度上“膨胀”了Child在事务之外的引用。

我在调试器中观察到,在JAX-RS已经接管了Child引用已变为非Child之后,确实在某些时候。

我认为null应该保留Child或者应该抛出某种异常来表示有人试图访问延迟加载的字段。显然我误解了一些事情。

在什么情况下,分离的JPA实体可能会在交易之外“夸大”其懒惰的关系?

如果重要的话,我通过Glassfish 4.1和EclipseLink 2.5.2(再次通过Glassfish 4.1)使用Jersey 2.10.4。

2 个答案:

答案 0 :(得分:0)

如果它真正“分离”,那么就没有上下文,因此没有加载。如果它仍然在上下文中,那么很明显它可以加载字段。这是根据JPA规范。

除非您使用某些特定于供应商的选项,否则您不遵循JPA规范,因此不能在任何其他JPA实现中依赖它...

答案 1 :(得分:0)

如果您只是阅读实体,则无需启动交易。例如,以下代码不需要事务:​​

ParentEntity pe = entityManager.find(ParentEntity.class,1);
List<ChildEntity> childs = pe.getChildList();
System.out.println(childs.size());

但请注意,只要您不在交易范围内,就无法对这些实体进行任何更改。