HibernateLazy加载问题怎么解决-创新互联

这篇文章主要讲解了“Hibernate Lazy加载问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate Lazy加载问题怎么解决”吧!

站在用户的角度思考问题,与客户深入沟通,找到开封网站设计与开封网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站制作、成都网站制作、企业官网、英文网站、手机端网站、网站推广、域名注册、虚拟空间、企业邮箱。业务覆盖开封地区。

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了!

感谢各位的阅读,以上就是“Hibernate Lazy加载问题怎么解决”的内容了,经过本文的学习后,相信大家对Hibernate Lazy加载问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


新闻名称:HibernateLazy加载问题怎么解决-创新互联
当前地址:http://pwwzsj.com/article/dphicg.html