您的位置:首页 > 编程语言 > Java开发

spring Junit下的延迟加载问题(Hibernate)

2016-04-20 10:16 513 查看
在使用spring管理junit下的Hibernate时,会出现org.hibernate.LazyInitializationException: could not initialize proxy - no Session,原因大家都知道,当session关闭后,你访问对象中的延迟加载属性,都会报session已关闭的错误。解决办法一般有四种:

1、在关闭session之前,使用Hibernate.initialize(Object proxy)强制加载

2、在关闭session之前,对延迟属性进行一次get访问

3、使用hql预加载,一般会用到fetch语句

4、hbm映射文件中,让集合或对象属性的
lazy=false

以面四种方式,如果用在与spring整合后的hibernate中,方式1、方式2可能不太好合,除非你使用模板的execute回调,在项目中是如何解决的呢?采用openSessionInView过滤器,该过滤器非常有效,会保证在同一次请求中,打开一个session,在当次请求中,打开不会关闭(具体底
层实现用到了ThreadLocal类),请求结束后spring会妥善处理好session的。有了 openSessionInView,我们几乎看不到延迟加载错误了,但是,在开发中我们又遇到了另一个严峻的问题,我们在业务层的测试代码中,却无法开 启openSessionInView,这就出现了,在action及页面中都正常的代码,拿到junit测试中却无法通过,这该如何是好?解决办法如
下:

在你的测试类中的setUp和tearDown中,加上下面的代码,注意,要把sessionFactory定义到外面。

private SessionFactory sessionFactory;

public void setUp() throws Exception {

sessionFactory = (SessionFactory) beanFactory.getBean("sessionFactory");

Session s = sessionFactory.openSession();

TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));

}

public void tearDown() throws Exception {

SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

Session s = holder.getSession();

s.flush();

TransactionSynchronizationManager.unbindResource(sessionFactory);

}

上面的代码是纯junit下的测试,如果你用了AbstractTransactionalSpringContextTests作为测试基类,sessionFactory的初始化就没有这么复杂了,直接由spring注入进来即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: