hibernate的延迟检索问题

代码如下

java 代码
  1. ......   
  2. Family family = (Family) this.getRequest().getSession().getAttribute("family");   
  3. familyId = family.getFamilyid();   
  4. Set systemdata = family.getSystemdatas();   
  5. ......  

 

报异常:org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed

上网查了之后,原因是hibernate的延迟检索lazyInitialization=true的时候

当执行Session的load()方法时,Hibernate不会立即执行查询Family表的select语句,仅仅返回Family类的代理类的实例,这个代理类具由以下特征:

(1) 由Hibernate在运行时动态生成,它扩展了Family类,因此它继承了Family类的所有属性和方法,但它的实现对于应用程序是透明的。
(2) 当Hibernate创建Family代理类实例时,仅仅初始化了它的familyId属性,其他属性都为null,因此这个代理类实例占用的内存很少。
(3)当应用程序第一次访问Family代理类实例时(例如调用family.getXXX()或family.setXXX()方法), Hibernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库中加载Family对象的所有数据。但有个例外,那就是当应用程序访问Family代理类实例的getFamilyId()方法时,Hibernate不会初始化代理类实例,因为在创建代理类实例时familyId就存在了,不必到数据库中去查询。Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具,它能够在程序运行时动态生成扩展 Java类或者实现Java接口的代理类。

如果在整个Session范围内,应用程序没有访问过Family对象,那么Family代理类的实例一直不会被初始化,Hibernate不会执行任何select语句。

上面那段代码由于引用变量family引用的Family代理类的实例在Session范围内始终没有被初始化,因此在执行family.getSystemdatas()方法时,Hibernate会抛出异常:

由此可见,Family代理类的实例只有在当前Session范围内才能被初始化。

java 代码
  1. ......   
  2. Session ssesion = persistence.getHibernateSession();   
  3. Transaction ts = ssesion.beginTransaction();   
  4. ssesion.load(Family.class,familyId);   
  5. Hibernate.initialize(family);   
  6. Set systemdata = family.getSystemdatas();   
  7. ......  

ok,问题解决了

你可能感兴趣的:(Hibernate)