当分离在Eclipselink中未按预期工作时,对惰性(未加载)集合的JPA调用方法

Fil*_*lou 5 java jpa entitymanager detach eclipselink

最近我尝试了一点JPA,试图更多地理解整个框架.我使用Eclipselink作为JPA提供程序.

我有两个实体有一个@OneToMany关系(一个人有很多地址)是懒惰加载.

当我加载一个人实体,分离它然后尝试访问(未加载)地址...它作为一个魅力.在调试时,我可以看到在执行size()地址列表的方法时执行了数据库查询.

我不明白为什么会有效.我希望有某种例外.我在最后几天(即这个链接)已经阅读了很多关于jpa等的内容,但是所有内容都指出了我不应该工作的结论.

任何人都可以解释为什么有效吗?

@Stateless
public class Test {
    @PersistenceContext(unitName="TestPU") EntityManager em;

    public void test() {
        Person person = em.find(Person.class, 1);

        System.out.println(person);

        System.out.println("em.contains(person): " + em.contains(person);

        em.detach(person);

        System.out.println("em.contains(person): " + em.contains(person);

        person.getAddresses().size();

        System.out.println("em.contains(person): " + em.contains(person);

        System.out.println(person);

    }
}
Run Code Online (Sandbox Code Playgroud)

结果日志将是

DEBUG: SELECT ... from PERSON WHERE (id = ?)
Person{id=1, name=Test, addresses={IndirectList: not instantiated}}
em.contains(person): true
em.contains(person): false
DEBUG: SELECT ... FROM ADDRESSES where (address_fk = ?)
em.contains(person): false
Person{id=1, name=Test, addresses={[Address{id=10, city=Testcity}]}}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 1

如此处所述,分离将从上下文中删除实体,以便不再对其进行管理。由于上下文仍然可用,因此如果需要,仍然可以获取未触发的惰性集合,并且 EclipseLink 认为这比抛出异常更有价值。这被认为是 EclipseLink 的一项功能,并且是 JPA 规范所允许的,尽管其他提供程序默认情况下未启用该行为。