温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Hibernate Lazy加载问题怎么解决

发布时间:2021-12-06 09:40:25 来源:亿速云 阅读:213 作者:iii 栏目:编程语言

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

Hbm文件

<bean id="BookItemRepositoryImpl"
class="domain.repository.hibernate.BookItemRepositoryImpl">

<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">

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

true
true
false
false

org.hibernate.dialect.Oracle9Dialect


<bean id="dataSource"
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文件中,把

<class name="BookItem" table="T_BookItem" 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了呢?,那这样的话还谈什么事务控制呢)。于是我进行了如下事务配置

<bean id="BookItemRepositoryImpl"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<bean
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加载问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI