日期:2014-05-20  浏览次数:20792 次

HibernateTemplate.load(class,id) 出现异常
spring 2.5 + Hibernate 3.1 
使用Spring 的 HibernateTemplate

Java code

public class HelloDaoImpl extends HibernateDaoSupport implements HelloDao {

    public Hello loadHelloById(Long id) {
1.        Session session=getSession();
          return (Hello) session.load(Hello.class,id);

2.       //return (Hello) getHibernateTemplate().load(Hello.class,id);
    }
}




调用代码:

Java code


        Hello hello = dao.loadHelloById(new Long(1));
3:      System.out.println(hello.getId());



1.如果使用 session.load 没有问题,
2.如果使用 hibernateTemplate.load(),在执行到3处抛出异常:

Java code

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    at dragon.spring.hello.orm.module.Hello$$EnhancerByCGLIB$$c60e1fef.setMessage(<generated>)
    at dragon.spring.hello.orm.HibernateMain.main(HibernateMain.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)







------解决方案--------------------
load执行的时候并不会执行SQL语句,只是取得对对象的引用,当你调用object.getXXX()的时候才会执行SQL语句,而如果你执行object.getXXX()的时候,相应的SESSION已经被关闭了,就会出现如上的情况,getHibernateTemplate()就是这样的情况。
像LZ这种情况,如果要用getHibernateTemplate,然后要在另外一个方法或者类里取得被返回对象的属性而不报这种异常,有着几种方法。
1。如果是WEB应用,可以在web.xml里加入OpenSessionInView这个filter,这样的话每次请求都会帮你维护一个session对象而不关闭
2。用Spring的HibernateInterceptor来作为拦截器,或者说代理,也会帮你在某个BEAN的方法执行开始创造一个SESSION。方法结束后关闭。
3。如果你要里面的XX属性,建议在执行getHibernateTemplate().load()这个方法的方法里面直接运行一次object.getXX(),这样就会把东西取出来了。
或者直接Hibernate.Initial(Object);