Hibernate Lazy 加载问题的解决

今天在写Spring+Hibernate的时候,遇到了Hibernate Lazy 加载的问题,后来经过调整配置解决了一个恼人的问题。现将解决方案和大家分享一下。




SEQBOOKID














Hbm文件

class="domain.repository.hibernate.BookItemRepositoryImpl">





class="org.springframework.orm.hibernate3.HibernateTemplate">











classpath:domain/BookItem.hbm.xml
classpath:domain/BookStore.hbm.xml



true
true
false
false

org.hibernate.dialect.Oracle9Dialect




class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">

oracle.jdbc.driver.OracleDriver


jdbc:oracle:thin:@192.168.10.28:1521:VIPDBZJ


scott


tiger

Sping配置文件

最开始的时候,服务代码是这样写的

public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem) getHibernateTemplate().load(
BookItem.class, new Long(bookItemId));
return bookItem;
}

JUNIT测试代码如下

public class BookItemRepositoryTest extends TestCase {
BookItemRepository bookItemRepo=null;

protected void setUp() throws Exception {
ApplicationContext context=new
ClassPathXmlApplicationContext("spring-context.xml");
bookItemRepo=(BookItemRepository)context.getBean("BookItemRepositoryImpl");

}

public void testFindById(){
BookItem item=bookItemRepo.findById(30);
assertEquals("123456", item.getBook().getISBN());
assertEquals("QiuHongBookStore", item.getBookStore().getName());

}

}

测试运行以后报下列错误

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 domain.BookItem$$EnhancerByCGLIB$$2f924ddd.getBook()
at test.domain.repository.hibernate.BookItemRepositoryTest.testFindById(BookItemRepositoryTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
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)

开始我在HBM文件中,把

lazy="true".....

然后就正常了。但是这样的代价是取消延迟加载,在load的时候直接进行加载。如果这样的话,在对象很大的时候性能会很差。于是在网上查资料。这个主要是HibernateTemplate在加载的时候,采用是lazy 加载方法,因为HibernateTemplat 在load完成后自动的关闭了Session,所以造成了LazyInitializationException异常。

我最开始将代码改成如下,也能解决这个问题。

public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem)getSession().load(
BookItem.class, new Long(bookItemId));
return bookItem;
}

但是这样改我心里面没有地,我担心会不会存在Session没有关闭或者泄漏的问题。

后来我联想如果在Spring中增加事务控制,那么HibernateTemplate是不是就不会在调用完成后马上Close Session了呢?(如果Close了Session,那事务是不是都需要Commit或RollBack了呢?,那这样的话还谈什么事务控制呢)。于是我进行了如下事务配置

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">




class="domain.repository.hibernate.BookItemRepositoryImpl">







PROPAGATION_REQUIRED


然后代码也进行了修改,执行手工加载操作。

public BookItem findById(long bookItemId) {
BookItem bookItem = (BookItem) getHibernateTemplate().load(
BookItem.class, new Long(bookItemId));

getHibernateTemplate().initialize(bookItem); // 手工加载每个对象
getHibernateTemplate().initialize(bookItem.getBook()); // 手工加载每个对象
getHibernateTemplate().initialize(bookItem.getBookStore()); //手工加载每个对象
return bookItem;
}

再进行测试就OK了!

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/90000/viewspace-1043221/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/90000/viewspace-1043221/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值