Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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_Java_Hibernate_Jpa_Jboss Arquillian_Glassfish Embedded - Fatal编程技术网

Java 为什么惰性抓取不起作用JPA

Java 为什么惰性抓取不起作用JPA,java,hibernate,jpa,jboss-arquillian,glassfish-embedded,Java,Hibernate,Jpa,Jboss Arquillian,Glassfish Embedded,我很难理解延迟抓取,因为我在一本书中读到关于它的内容时,我并不为它工作。他们说,在延迟抓取中,jpa只会在通过geters访问实体时加载实体,所以我创建了一个Arquillian项目来测试这个概念,但它不起作用。 这是我的两个实体 人 package com.actionbazaar.model; @Entity @TableGenerator( initialValue = 5, name = "PERSON_SEQ", table = "PE

我很难理解延迟抓取,因为我在一本书中读到关于它的内容时,我并不为它工作。他们说,在延迟抓取中,jpa只会在通过geters访问实体时加载实体,所以我创建了一个Arquillian项目来测试这个概念,但它不起作用。 这是我的两个实体

package com.actionbazaar.model;

@Entity
@TableGenerator(
        initialValue = 5,
        name = "PERSON_SEQ",
        table = "PERSON_SEQ_TABLE",
        pkColumnName = "SEQ_NAME",
        pkColumnValue = "PERSON",
        valueColumnName = "SEQ_VALUE")
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String fname;
    private String lname;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.PERSIST)
    List<Address> addresses;
    //getters and setters 
}
我有一个使用此方法的无状态会话bean

    public Person getFirstPerson() {
    Person p = em.find(Person.class, 1);
    em.detach(p);
    //why this call does not create an exception
    p.getAddresses().get(0);
    return p;
}
因为我在访问地址之前分离了实体,所以地址列表应该是空的,当我分离它时,它不再由entitymanager管理,所以我不应该获取此人的地址 问题是,我可以获取那个人的地址,即使我在访问InBG地址字段之前延迟获取地址字段并分离实体!!!! 请有人解释一下

其他测试

Person p= myStatlessSessionBean.getFirstPerson();
myOtherStalessSesionBean.moveAllPeopleToCity("NY");
if(p.getAddresses().get(0).getCity().equals("NY"))
{
  system.out.prinln("person moved");
}
else {
system.out.prinln("person did not move");
} //prompts person did not move

您仅分离父实体Person。您没有分离子实体、地址,当您获得地址时,它指的是仍然由持久性上下文管理的实体

如果还希望分离子级,则应使用CascadeType.DETACH


您可能会说,“但是我的FetchType设置为LAZY!”。仅仅因为它是懒惰的,并不意味着对象是空的。Hibernate返回集合类型的代理对象,一旦您尝试访问它们,它将填充它们的值。

是的,伙计,您是对的。你没有做错什么。我刚刚打开了《专业JPA 2》第二版的书,发现了这本书:

您正在使用glassfish embedded,这实际上是导致问题的原因。你的代码没有问题。正如上述书的作者所说

一些供应商可能会 尝试解析关系,而其他人可能只是抛出异常或使属性未初始化

因此,在您的情况下,关系得到解决,而不是延迟加载。只要使用其他供应商实现相同的示例,您就不会遇到任何问题。在这里使用glassfish嵌入,lazyfetch不起作用。否则,应该抛出异常,因为变量
p
已分离

这里是我阅读这篇美丽信息的地方


这是上面链接中的快照

第二次测试如何!,我已将级联更改为添加CascadeType.DETACH,但仍然存在相同的问题,首先我想知道是否正确理解了我所期望的概念和行为,我同意@Tahir。根据JPA规范:“当需要跨供应商的互操作性时,应用程序不得使用延迟加载。”JPA规范还提到延迟获取只是一个提示,这告诉我它的实现留给供应商。是的。。你是对的。。我很想知道为什么会发生这种事。获得更多信息。谢谢@achabahe@achabahe我怀疑这就是原因,但是你用“hibernate”标记了你的问题,尽管看起来你没有使用它。这有误导性。可能他是想接近冬眠熟人:D@JBNizet^_^
Person p= myStatlessSessionBean.getFirstPerson();
myOtherStalessSesionBean.moveAllPeopleToCity("NY");
if(p.getAddresses().get(0).getCity().equals("NY"))
{
  system.out.prinln("person moved");
}
else {
system.out.prinln("person did not move");
} //prompts person did not move