Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 分离时惰性(未加载)集合上的JPA调用方法在Eclipselink中未按预期工作_Java_Jpa_Eclipselink_Entitymanager_Detach - Fatal编程技术网

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

Java 分离时惰性(未加载)集合上的JPA调用方法在Eclipselink中未按预期工作,java,jpa,eclipselink,entitymanager,detach,Java,Jpa,Eclipselink,Entitymanager,Detach,最近我对JPA做了一些实验,试图进一步了解整个框架。我使用Eclipselink作为JPA提供商 我有两个实体,它们的@OneToMany关系(一个人有许多地址)是延迟加载的 当我加载个人实体时,将其分离,然后尝试访问(未加载的)地址。。。它是一种魅力。调试时,我可以看到在执行地址列表的size()方法时执行了数据库查询 我不明白为什么会这样。我希望会有例外。在过去的几天里,我读了很多关于jpa之类的东西,但所有的东西都让我得出了这样的结论:它不应该起作用 有人能解释一下为什么会这样吗 @Sta

最近我对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);

    }
}
生成的日志将是

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}]}}

如上所述,“分离”将从上下文中删除实体,以便不再对其进行管理。由于上下文仍然可用,如果需要,仍然可以获取未迁移的惰性集合,EclipseLink认为这比抛出异常更有价值。这被认为是EclipseLink的一个特性,JPA规范允许这样做,尽管默认情况下其他提供者没有启用该行为

因为使用EclipseLink,它们并没有按照JPA规范的意图“分离”对象(即从数据库断开连接),所以它们保留连接信息。。。因此,它检索字段(即使如果它真的“分离”,则不应该)。如果您在其他JPA提供程序上执行了相同的操作,通常在字段未分离的情况下,他们会抛出异常。您可以通过调用感谢您的澄清来检查实体是否正确分离。尽管我不确定JPA规范是否允许这种行为。我不是阅读规范的专家,但据我所知,以下引用不允许这种行为。
只有当关联实例可用时,才能安全访问关联实例的可用状态。
(JSR 338第3.2.7节分离实体)指出行为未定义,并不是说它需要一个异常,EclipseLink是规范的参考实现。之后访问关系是不安全的,因为实体可以随时序列化,从而中断与上下文的连接(即使它仍然打开)。您是对的,这不是禁止的。没有什么不可以。我只需要更习惯于阅读说明书。再次感谢您的澄清!