为什么延迟获取不工作 JPA
Why Lazy Fetching is not working JPA
我很难理解延迟获取,因为我不工作,因为我在一本书中读到过它,他们说在延迟获取中,只有通过 geters 访问它们时,jpa 才会加载实体,所以我创建了一个 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
}
地址
@Entity
public class Address implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String city;
private String zip;
private String street;
@ManyToOne
private Person owner;
//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;
}
因为我在访问地址之前分离了实体,所以地址列表应该是空的,当我分离它时,它不再由实体管理器管理,所以我不应该为这个人获取地址
问题是我可以获取那个人的地址,即使我有地址字段的延迟获取并在访问地址字段之前分离实体!!!!
请一些人有解释。
另一个测试
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
您只是在分离 parent 实体,Person。您没有分离 children 个实体、地址,当您获得地址时,它指的是仍然由持久性上下文管理的实体。
如果你也想分离 children,你应该使用 CascadeType.DETACH。
你可能会说,"But my FetchType is set to LAZY!"。仅仅因为它是 LAZY,并不意味着 object 为空。 Hibernate returns 集合类型的代理 objects,一旦您尝试访问它们,它将填充它们的值。
是的伙计,你是对的。你在这里没有做错任何事。我刚刚打开 Pro JPA 2,第 2 版书籍,发现了这个:
您正在使用 glassfish-embedded,这实际上是导致问题的原因。你的代码没有问题。正如上述书籍的作者所说,
Some vendors might
attempt to resolve the relationship, while others might simply throw an exception or leave the attribute uninitialized.
因此,在您的情况下,关系已解决而不是延迟加载。只需使用其他供应商实施相同的示例,您就不会遇到任何问题。这里使用glassfish-embedded、lazyfetch是不行的。否则应抛出异常,因为变量 p
已分离。
这里是 link 我也读到了这篇漂亮的信息
这是上面的截图link
我很难理解延迟获取,因为我不工作,因为我在一本书中读到过它,他们说在延迟获取中,只有通过 geters 访问它们时,jpa 才会加载实体,所以我创建了一个 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
}
地址
@Entity
public class Address implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String city;
private String zip;
private String street;
@ManyToOne
private Person owner;
//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;
}
因为我在访问地址之前分离了实体,所以地址列表应该是空的,当我分离它时,它不再由实体管理器管理,所以我不应该为这个人获取地址 问题是我可以获取那个人的地址,即使我有地址字段的延迟获取并在访问地址字段之前分离实体!!!! 请一些人有解释。
另一个测试
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
您只是在分离 parent 实体,Person。您没有分离 children 个实体、地址,当您获得地址时,它指的是仍然由持久性上下文管理的实体。
如果你也想分离 children,你应该使用 CascadeType.DETACH。
你可能会说,"But my FetchType is set to LAZY!"。仅仅因为它是 LAZY,并不意味着 object 为空。 Hibernate returns 集合类型的代理 objects,一旦您尝试访问它们,它将填充它们的值。
是的伙计,你是对的。你在这里没有做错任何事。我刚刚打开 Pro JPA 2,第 2 版书籍,发现了这个:
您正在使用 glassfish-embedded,这实际上是导致问题的原因。你的代码没有问题。正如上述书籍的作者所说,
Some vendors might attempt to resolve the relationship, while others might simply throw an exception or leave the attribute uninitialized.
因此,在您的情况下,关系已解决而不是延迟加载。只需使用其他供应商实施相同的示例,您就不会遇到任何问题。这里使用glassfish-embedded、lazyfetch是不行的。否则应抛出异常,因为变量 p
已分离。
这里是 link 我也读到了这篇漂亮的信息
这是上面的截图link