Spring为我们解决Hibernate的Session的关闭与开启问题。 Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Session 范围之内进行。如果 Service 层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常 (eg: org.hibernate.LazyInitializationException:(LazyInitializationException.java:42) - failed to lazily initialize a collection of role: cn.easyjava.bean.product.ProductType.childtypes, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: cn.easyjava.bean.product.ProductType.childtypes, no session or session was closed)。 用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。 而Spring为我们提供的OpenSessionInViewFilter过滤器为我们很好的解决了这个问题。OpenSessionInViewFilter的主要功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。 OpenSessionInViewFilter 过滤器将 Hibernate Session 绑定到请求线程中,它将自动被 Spring 的事务管理器探测到。所以 OpenSessionInViewFilter 适用于 Service 层使用HibernateTransactionManager 或 JtaTransactionManager 进行事务管理的环境,也可以用于非事务只读的数据操作中。
<filter> <filter-name>Spring OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <!-- 指定org.springframework.orm.hibernate3.LocalSessionFactoryBean在spring配置文件中的名称,默认值为sessionFactory 如果LocalSessionFactoryBean在spring中的名称不是sessionFactory,该参数一定要指定,否则会出现找不到sessionFactory的例外 --> <param-name>sessionFactoryBean</param-name> <param-value>sessionFactory</param-value> </init-param> </filter> <filter-mapping> <filter-name>Spring OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- private SessionFactory sessionFactory;
-
-
- protected void setUp() throws Exception {
- super.setUp();
- sessionFactory = (SessionFactory) SpringContext.getInstance().getBean(
- "sessionFactory");
-
- Session s = sessionFactory.openSession();
- TransactionSynchronizationManager.bindResource(sessionFactory,
- new SessionHolder(s));
-
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- SessionHolder holder = (SessionHolder) TransactionSynchronizationManager
- .getResource(sessionFactory);
- Session s = holder.getSession();
- try {
- s.flush();
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
- TransactionSynchronizationManager.unbindResource(sessionFactory);
- SessionFactoryUtils.closeSession(s);
- }
SpringContext.class - public class SpringContext {
-
- private static SpringContext m_instance;
-
- private static String[] contextFiles = new String[] { "applicationContext.xml" };
-
- private ApplicationContext ctx;
-
- public SpringContext() {
- ctx = new ClassPathXmlApplicationContext(contextFiles);
- }
-
- public SpringContext(String[] setting) {
- ctx = new ClassPathXmlApplicationContext(setting);
- }
-
- public synchronized static SpringContext getInstance() {
- if (m_instance == null) {
- m_instance = new SpringContext(contextFiles);
- }
- return m_instance;
- }
-
- public Object getBean(String beanId) {
- Object o = ctx.getBean(beanId);
- if (o instanceof TransactionProxyFactoryBean) {
- TransactionProxyFactoryBean factoryBean = (TransactionProxyFactoryBean) o;
- o = factoryBean.getObject();
- }
- return o;
- }
-
- }
@Before
public void openSession() throws Exception {
dsContext = new FileSystemXmlApplicationContext(configStr);
sessionFactory = (SessionFactory) dsContext.getBean("sessionFactory");
session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.MANUAL);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
@After
public void closeSession() throws Exception {
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.releaseSession(session, sessionFactory);
}
|