我很难理解懒惰的提取,因为我没有工作,因为我在书中读到它,他们说在懒惰的提取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
}
地址
@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
答案 0 :(得分:4)
您正在使用 glassfish-embedded ,这实际上是导致问题的原因。你的代码没有问题。正如上述书的作者所提到的,
有些供应商可能会 尝试解决这种关系,而其他人可能只是抛出异常或保持属性未初始化。
因此,在您的情况下,关系得到解决而不是延迟加载。只需使用其他供应商实施相同的示例,您就不会遇到任何问题。这里使用glassfish-embedded, lazyfetch 不起作用。否则应抛出异常,因为变量self.style.configure("ciao.TLabel", background="red")
已分离。
这里是link,我也阅读了这段美丽的信息
的快照答案 1 :(得分:1)
您只是分离父实体Person。您没有分离子实体,地址,当您获取地址时,它指的是仍由持久性上下文管理的实体。
如果你想要分离孩子,你应该使用CascadeType.DETACH。
你可能会说,“但我的FetchType设置为LAZY!”。仅仅因为它是LAZY,并不意味着该对象为空。 Hibernate返回集合类型的代理对象,一旦您尝试访问它们,它将填充它们的值。