在尝试对延迟加载进行一些测试时,为了检查我是否理解它,我完全感到困惑。
这是我在测试中使用的实体:
@Entity
public class Family {
@Id
private int id;
@OneToMany(mappedBy="family", fetch=FetchType.LAZY)
private Set<Person> members;
//getters & setters
public String toString(){
String s="";
for(Person p:getMembers()){
s+=p.getFirstName();
}
return s;
}
}
@Entity
public class Person implements Comparable<Person>{
@Id
private int id;
private String firstName;
private String lastName;
@ManyToOne
private Family family;
//getters &setters
}
这是我的主要方法:
public static void main(String[] args) {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
em = factory.createEntityManager();
Query q = em.createQuery("select f from Family f");
List<Family> families= q.getResultList();
em.clear();
em.close();
factory.close();
for(Family f:families){
System.out.println(f);
}
}
我从延迟加载中理解的是,如果属性被标记为懒惰地获取,并且在管理时不被访问,则它将不会被加载到内存中,并且以后任何尝试访问它都将无法工作。现在令我困惑的是,即使在关闭EM和EMF之后,通过分离的族列表访问惰性成员属性时,上述测试也没有任何问题! ......那是正常的吗?我错过了解懒惰的装载概念吗?
注意:我正在使用带有嵌入式数据库的J2SE环境。我的提供者是EclipseLink
先谢谢你 乔治
答案 0 :(得分:2)
确保您使用的是eclipselink代理,或使用静态编织。如果你两个都不使用,那么LAZY将不会被编织,你将拥有EAGER。
此外,EclipseLink支持在EntityManager关闭后访问LAZY关系。 虽然工厂关闭后没有。但是,如果对象在缓存中,那么它也可以在关闭后工作。此外,如果您在同一个持久性单元上打开了另一个工厂,则持久性单元仍处于打开状态。
答案 1 :(得分:2)
检查在关闭工厂之前是否未触发toString方法,例如是否正在记录实体。我不建议在toString方法中触发关系,因为这容易出错并且可能会意外触发。打开EclipseLink日志记录将有助于向您展示在工厂生命周期中访问它的位置,假设它不是问题的一部分。
答案 2 :(得分:0)
这可能是因为JPA提供程序不需要使用延迟初始化。它不是JPA提供者的必需条件,而是a hint。
当指定FetchType.EAGER
时,JPA需要急切地获取数据,但在指定FetchType.LAZY
时不需要懒惰地获取数据。