getCurrentSession及openSession正确打开方式(既管治病,还管死活)(针对hibernate4.3.2版本)
2018-01-23 15:06
323 查看
接上篇我们看到在spring配置文件中,配置了事务,这样在使用getCurrentSession时,只需要在方法上加上@Transcational注解即可,需要注意的是,不管你执行什么操作,哪怕是查询,你依然需要事务的控制。这跟上一篇提到的只有进行DDL才需要事务是两个概念,getCurrentSession是spring管理的对象所共享的,在执行sql时,需要事务保证数据的一致性。这句话另外一层意思是,只有在spring管理的对象中,使用getCurrentSession才能获取到有效的且是spring控制事务的session。
如果自己new对象,即便你把sessionFactory这个对象传入对象内部,使用getCurrentSession依然会报错。如果你根据报错去搜索,大致会搜索到这么一个结论,需要在hibernate.cfg.xml中添加一个属性
一、 不添加hibernate.current_session_context_class属性,并且在spring管理的对象之外使用getCurrentSession,代码及报错如下:无论get方法有没有@Transcational注解,都报相同的错误,可见@Transcational在这里并没有生效
二、加上hibernate.current_session_context_class属性,但是去掉Test1Dao中的事务,会发现,getCurrentSession需要事务的支持
三、更新操作不生效,这个问题是针对openSession,这种方式获取的session并不会自动提交,需要执行flush方法才能够更新数据。
如果自己new对象,即便你把sessionFactory这个对象传入对象内部,使用getCurrentSession依然会报错。如果你根据报错去搜索,大致会搜索到这么一个结论,需要在hibernate.cfg.xml中添加一个属性
<property name="hibernate.current_session_context_class">thread</property>加上这个属性之后,使用getCurrentSession确实可以获取到session对象,但此时,该对象并没有事务的控制,需要你自己去控制事务。接下来我们可以来看一些有意思的错误:
一、 不添加hibernate.current_session_context_class属性,并且在spring管理的对象之外使用getCurrentSession,代码及报错如下:无论get方法有没有@Transcational注解,都报相同的错误,可见@Transcational在这里并没有生效
public class Test1Dao { private SessionFactory sessionFactory; //通过构造器传入SessionFactory对象 public Test1Dao(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional public List get() { try { Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); List list = sessionFactory.getCurrentSession().createSQLQuery("SELECT * from test_info").addEntity(TestInfo.class).list(); transaction.commit(); return list; } catch (Exception e) { e.printStackTrace(); return null; } } }
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) at com.ucredit.test.Test1Dao.get(Test1Dao.java:24) at com.ucredit.test.TestController.get(TestController.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at aa21 org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
二、加上hibernate.current_session_context_class属性,但是去掉Test1Dao中的事务,会发现,getCurrentSession需要事务的支持
public class Test1Dao { private SessionFactory sessionFactory; //通过构造器传入SessionFactory对象 public Test1Dao(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional public List get() { try { Session session = sessionFactory.getCurrentSession(); // Transaction transaction = session.beginTransaction(); List list = sessionFactory.getCurrentSession().createSQLQuery("SELECT * from test_info").addEntity(TestInfo.class).list(); // transaction.commit(); return list; } catch (Exception e) { e.printStackTrace(); return null; } } }
org.hibernate.HibernateException: createSQLQuery is not valid without active transaction at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352) at com.sun.proxy.$Proxy88.createSQLQuery(Unknown Source) at com.ucredit.test.Test1Dao.get(Test1Dao.java:26) at com.ucredit.test.TestController.get(TestController.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
三、更新操作不生效,这个问题是针对openSession,这种方式获取的session并不会自动提交,需要执行flush方法才能够更新数据。
public class Test1Dao { private SessionFactory sessionFactory; //通过构造器传入SessionFactory对象 public Test1Dao(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void update() { Session session = sessionFactory.openSession(); TestInfo testInfo = (TestInfo) session.createSQLQuery("SELECT * from test_info").addEntity(TestInfo.class).uniqueResult(); testInfo.setName("测试"); session.update(testInfo); } }我在hibernate配置文件中设置了打印sql,但在控制台只看到了select语句,没有看到update,数据库也没有更新,但加上session.flush()后,执行结果如下:
Hibernate: SELECT * from test_info Hibernate: update test_info set key_id=?, name=? where id=?
相关文章推荐
- hibernate中session的产生方式(openSession、getCurrentSession)
- hibernate获取session的两种方式分别是openSession() 方法和getCurrentSession() 方法。
- Hibernate getCurrentSession 与 openSession() 的区别
- Hibernate中的getCurrentSession和openSession
- Hibernate getCurrentSession 与 openSession() 的区别
- hibernate中的SessionFactory的openSession与getCurrentSession
- Rhyme/Hibernate getCurrentSession()与openSession()的区别
- hibernate的SessionFactory的getCurrentSession 与 openSession() 的区别
- Hibernate中的openSession(),getSession() 和 getCurrentSession() 的区别
- Hibernate——openSession()和getCurrentSession()的异同
- (hibernate之一)Sessionfactory的getCurrentSession与openSession的区别
- 【Hibernate】SessionFactory中的getCurrentSession()和openSession()的区别
- Hibernate的getCurrentSession()和openSession()的区别和使用
- Hibernate 中 openSession()和getCurrentSession() 的区别
- Hibernate3.1之后的openSession() VS getCurrentSession()
- hibernate 的 openSession 和 getCurrentSession 的实现
- Hibernate4之getCurrentSession和openSession
- hibernate 的SessionFactory的getCurrentSession 与 openSession() 的区别
- hibernate中openSession()跟getCurrentSession()方法之间的区别
- hibernate: openSession() 和getCurrentSession()的区别