异常:org.hibernate.LazyInitializationException

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 com.hibernate.bean.Booktype$$EnhancerByCGLIB$$f34a40bf.getName()
 at test.TestBookinfoBizImpl.testFindAllBookinfos(TestBookinfoBizImpl.java:129)
 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:597)
 at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
 at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
 at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
 at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
 at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
 at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
 at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
 at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
 at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
 at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

问题分析:

这里报的是:数据延迟加载异常!

当取关联对象的非主键的其他字段的值,都会延迟加载(hibernate默认的)!由于当hibernate交给spring进行管理之后,连接对象实际上已经交给spring的一个叫TransactionAsychronizationManager进行管理, 默认的,在执行一个操作后,session将被关闭.这时如果代码访问的数据涉及延迟加载,将抛出延迟加载异常;

 

 

 

解决办法:

 

1。可以在多的一方(假定为A类)设置lazy = “FALSE”,即不延迟加载数据!

但是也有一些问题,就是当我不需要使用到一方(B类)的数据时,hibernate也会帮我把B的数据加载出来,这样一来的话,对程序的性能就有影响!所以我会采用下面这种优雅一点的方法!

 

值得注意的是:下面我所解决的只能是在Jnit的测试类中才可以手动配置连接对象的开启和关闭

2。下面的配置比较复杂,所以把思路整理了一下!但是通过手动编码就可以把后台类(数据访问层)进行一次完整的测试(增删改查--包括延迟加载),

 

 

手动配置如下:

@Before
 public void setUp() throws Exception {
  
  String config = "applicationContext.xml";
   ctx = new ClassPathXmlApplicationContext(config);
  
  bookinfoBiz = (IBookinfoBiz)ctx.getBean("BookinfoBizImpl");
  booktypeBiz = (IBooktypeBiz)ctx.getBean("BooktypeBizImpl");
  
  //获得sessionFactory
     sessionFactory = (SessionFactory)ctx.getBean("sessionFactory");

  //手动编码打开session
  
  Session session = sessionFactory.openSession();
  
  //将session保存在SessionHolder ,并由TransactionSynchronizationManager进行管理
  //保存
  SessionHolder sessionHolder = new SessionHolder(session);
  //管理,绑定到本地线程
  TransactionSynchronizationManager.bindResource(sessionFactory,sessionHolder);
  
 
 }

 @After
 public void tearDown() throws Exception {
       //1.取出session
  
 SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
 
 Session session = sessionHolder.getSession();
 //清除
 session.flush();
  
 //从本地线程中取消绑定
 TransactionSynchronizationManager.unbindResource(sessionFactory);
 
 //关闭连接
 SessionFactoryUtils.closeSession(session);
 }

 

 

 

 

 

你可能感兴趣的:(SSH)