junit测试之hiberante延迟加载有关问题

junit测试之hiberante延迟加载问题

很多新手都会遇到的hibernate session关闭时的延迟加载错误,我想原因大家都知道,当session关闭后,你去访问对象中的延迟加载属性,都会报session已关闭的错误。解决办法一般有四种:
1、hbm映射文件中,让集合或对象属性的 lazy=false
2、在关闭session之前,使用Hibernate.initialize(Object proxy)强制加载
3、在关闭session之前,对延迟属性进行一次get访问
4、使用hql预加载,一般会用到fetch语句
以面四种方式,如果用在与spring整合后的hibernate中,方式2、方式3可能不太好合,除非你使用模板的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注入进来即可。