spring中OpenSessionInViewFilter与SessionFactory.getCurrentSession()的冲突

g646585144 2013-05-30 10:07:53
spring中OpenSessionInViewFilter的问题:
如果在使用OpenSessionInViewFilter的时候在dao层使用的是SessionFactory.getCurrentSession(),
那么根据Hibernate中SessionFactory.getCurrentSession(),它会在事务提交的时候会关闭session,
如果是这样的话就跟OpenSessionInViewFilter延迟session的生命周期有些矛盾了。。。

...全文
213 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 9 楼 g646585144 的回复:
[quote=引用 8 楼 hjw506848887 的回复:] [quote=引用 7 楼 g646585144 的回复:] 也就是getCurentSession()在事务提交的时候session会关闭才对。。但是实施却没有关闭
事务如果你用getCurrentSession()事务提交后,你应该调用session.close()才能关闭呀,并不是你说的事务提交后就会自动关闭的。。。而hibernateTemplate要做的就是把这一切封装好了,不用你去手动关闭session。你理解错了。。。[/quote] 你去翻翻关于hibernate的getCurentSession()。这个方法会在事务提交的时候自动关闭的!无须手动关闭。 你还没看懂我要问的问题呢。。[/quote]额。。。好吧好吧,我当getCurrentSession()当成openSession()了,失误失误,嘿嘿嘿
dracularking 2013-05-31
  • 打赏
  • 举报
回复
public final Session currentSession() throws HibernateException {  
      //从线程局部量context中尝试取出已经绑定到线程的Session  
      Session current = existingSession( factory );  
       
      //如果没有绑定到线程的Session  
      if (current == null) {  
         //打开一个”事务提交后自动关闭”的Session  
         current = buildOrObtainSession();  
            current.getTransaction().registerSynchronization(buildCleanupSynch() );  
         // wrap the session in thetransaction-protection proxy  
         if ( needsWrapping( current ) ) {  
            current = wrap( current );  
         }  
         //将得到的Session绑定到线程中:即以<SessionFactory,Session>键值对方式设置到线程局部量context  
         doBind( current, factory );  
      }  
      return current;  
   }
我觉得是这样,只有当前session为null时才会去创建“事务提交后自动关闭”的Session,而使用了OpenSessionInViewFilter的session在当前请求范围内不会为null
zjlolife 2013-05-31
  • 打赏
  • 举报
回复
上楼说的比较靠谱哦!
zjlolife 2013-05-30
  • 打赏
  • 举报
回复
引用 2 楼 q35335010 的回复:
在ThreadLocal Session模式下面,只要提交了事务,那么session就自动关闭了 你的是这种模式吗
在hibernate中通过getCurrentSession()获取的session会在事务提交,关闭。 在OPenview中session在事务提交应该不会关闭 这样一来如果在openView中用了getCurrentSession,貌似会出现问题,有些矛盾
q35335010 2013-05-30
  • 打赏
  • 举报
回复
在ThreadLocal Session模式下面,只要提交了事务,那么session就自动关闭了 你的是这种模式吗
g646585144 2013-05-30
  • 打赏
  • 举报
回复
希望得到大家合理的解释!
g646585144 2013-05-30
  • 打赏
  • 举报
回复
引用 8 楼 hjw506848887 的回复:
[quote=引用 7 楼 g646585144 的回复:] 也就是getCurentSession()在事务提交的时候session会关闭才对。。但是实施却没有关闭
事务如果你用getCurrentSession()事务提交后,你应该调用session.close()才能关闭呀,并不是你说的事务提交后就会自动关闭的。。。而hibernateTemplate要做的就是把这一切封装好了,不用你去手动关闭session。你理解错了。。。[/quote] 你去翻翻关于hibernate的getCurentSession()。这个方法会在事务提交的时候自动关闭的!无须手动关闭。 你还没看懂我要问的问题呢。。
  • 打赏
  • 举报
回复
引用 7 楼 g646585144 的回复:
也就是getCurentSession()在事务提交的时候session会关闭才对。。但是实施却没有关闭
事务如果你用getCurrentSession()事务提交后,你应该调用session.close()才能关闭呀,并不是你说的事务提交后就会自动关闭的。。。而hibernateTemplate要做的就是把这一切封装好了,不用你去手动关闭session。你理解错了。。。
g646585144 2013-05-30
  • 打赏
  • 举报
回复
也就是getCurentSession()在事务提交的时候session会关闭才对。。但是实施却没有关闭
g646585144 2013-05-30
  • 打赏
  • 举报
回复
引用 5 楼 hjw506848887 的回复:
[quote=引用 4 楼 g646585144 的回复:] 经过测试以下代码发现spring已经处理这个了。。
package com.zjlolife.dao.impl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.zjlolife.dao.UserDao;
import com.zjlolife.domain.User;


public class UserDaoBean implements UserDao{
	
    @Resource
	private SessionFactory sessionFactory;
    
    public  HibernateTemplate getHibernateTemplate() {
    	return new HibernateTemplate(sessionFactory);
    }
	public User load() {
	   /*Session session = sessionFactory.getCurrentSession();
	   return  (User)session.load(User.class, 1);*/
		
		return getHibernateTemplate().load(User.class, 1);
	}

}
可是spring是怎么处理的呢?getCurrentSession会在事务提交的时候将session关闭的!spring是怎么处理的呢?上面两种方式 经测试都没有问题。。不知道为什么,希望大神来看看吧
你这么测试有问题才怪呢,你这么测试没什么意义的。这里你只有一个load对表的操作啊,如果你写了大堆对数据库操作的代码,比如:先查询,再修改,再查询,再删除,再保存,用hibernateTemple没有问题的,但是你再用Session session = sessionFactory.getCurrentSession();再进行上面的操作,可能会有错误的。因为hibernateTemplate已经把你的sessionFactory等东西做了一个封装,不用你每次都要opensession和关闭session。[/quote] 你没明白我的意思吧,我的意思是原先hibernate自己的一套获取session的方法,比如getCurrentSession(),这个方法会在事务提交的关闭session。 现在的问题是我如果使用了openview的话,按道理我通过getCurentSession()会在事务提交的时候关闭,可是经过我测试通过getCurentSession()获取的时候session并没有关闭,我只是很好奇spring是怎么处理这个的而已。。
  • 打赏
  • 举报
回复
引用 4 楼 g646585144 的回复:
经过测试以下代码发现spring已经处理这个了。。
package com.zjlolife.dao.impl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.zjlolife.dao.UserDao;
import com.zjlolife.domain.User;


public class UserDaoBean implements UserDao{
	
    @Resource
	private SessionFactory sessionFactory;
    
    public  HibernateTemplate getHibernateTemplate() {
    	return new HibernateTemplate(sessionFactory);
    }
	public User load() {
	   /*Session session = sessionFactory.getCurrentSession();
	   return  (User)session.load(User.class, 1);*/
		
		return getHibernateTemplate().load(User.class, 1);
	}

}
可是spring是怎么处理的呢?getCurrentSession会在事务提交的时候将session关闭的!spring是怎么处理的呢?上面两种方式 经测试都没有问题。。不知道为什么,希望大神来看看吧
你这么测试有问题才怪呢,你这么测试没什么意义的。这里你只有一个load对表的操作啊,如果你写了大堆对数据库操作的代码,比如:先查询,再修改,再查询,再删除,再保存,用hibernateTemple没有问题的,但是你再用Session session = sessionFactory.getCurrentSession();再进行上面的操作,可能会有错误的。因为hibernateTemplate已经把你的sessionFactory等东西做了一个封装,不用你每次都要opensession和关闭session。
g646585144 2013-05-30
  • 打赏
  • 举报
回复
经过测试以下代码发现spring已经处理这个了。。
package com.zjlolife.dao.impl;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.zjlolife.dao.UserDao;
import com.zjlolife.domain.User;


public class UserDaoBean implements UserDao{
	
    @Resource
	private SessionFactory sessionFactory;
    
    public  HibernateTemplate getHibernateTemplate() {
    	return new HibernateTemplate(sessionFactory);
    }
	public User load() {
	   /*Session session = sessionFactory.getCurrentSession();
	   return  (User)session.load(User.class, 1);*/
		
		return getHibernateTemplate().load(User.class, 1);
	}

}
可是spring是怎么处理的呢?getCurrentSession会在事务提交的时候将session关闭的!spring是怎么处理的呢?上面两种方式 经测试都没有问题。。不知道为什么,希望大神来看看吧
一,集成 Spring 与 Hibernate 1,配置SessionFactory 1,配置 ---------------------- applicationContext.xml ------------------------ ---------------------- jdbc.properties ------------------------ jdbcUrl = jdbc:mysql:///itcastoa driverClass = com.mysql.jdbc.Driver username = root password = 1234 2,测试代码 @Test// 测试 SessionFactory 的配置 public void testSessionFactory(){ SessionFactory sessionFactory = (SessionFactory) ac.getBean("sessionFactory"); Assert.assertNotNull(sessionFactory.openSession()); } 2,配置声明式事务(使用基于注解的方式) 1,配置 2,测试代码 1,Service类 @Service public class InsertUserService { @Resource private SessionFactory sessionFactory; @Transactional public void addUsers() { sessionFactory.getCurrentSession().save(new User()); // int a = 1 / 0; // 这行会抛异常 sessionFactory.getCurrentSession().save(new User()); } } 2,单元测试 @Test // 测试声明式事务 public void testTransaction() { InsertUserService service = (InsertUserService) ac.getBean("insertUserService"); service.addUsers(); } 3,在web.xml配置 springOpenSessionInView 过滤器(解决抛LazyInitializationException的问题) 1,配置 <filter> <filter-name>OpenSessionInViewfilter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilterfilter-class> filter> <filter-mapping> <filter-name>OpenSessionInViewfilter-name> *.do filter-mapping> 2,LazyInitializationException异常说明 1,对于集合属性,默认是lazy="true"的,在第一次使用时才加载。 2,但在加载时,如果Session已经关掉了就会抛LazyInitializationException异常 二,集成 Spring 与 Struts2.1.8.1 1,在web.xml配置监听器(Spring Reference 15.2 Common configuration) org.springframework.web.context.ContextLoaderListener contextConfigLocation /WEB-INF/classes/applicationContext*.xml 2,在struts-config.xml配置controller(Spring Reference 15.4.1.1. DelegatingRequestProcessor) 3,测试 1,写Action类与Service类 @Controller("testAction") @Scope("prototype") public class TestAction extends ActionSupport { @Resource private TestService testService; @Override public String execute(){ testService.saveTwoUser(); return SUCCESS; } } @Service public class TestService { @Resource private SessionFactory sessionFactory; @Transactional public void saveTwoUser() { sessionFactory.getCurrentSession().save(new User()); // int a = 1 / 0; // 这行会抛异常 sessionFactory.getCurrentSession().save(new User()); } } 2,在struts.xml配置Action /test.jsp 3,部署到Tomcat并访问测试。 4,说明: 1,在写Action时要指定 @Controller 与 @Scope("prototype") 2,在struts.xml配置action时,在class属性写bean的名称

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧