`
PolyAngel
  • 浏览: 112478 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

org.hibernate.HibernateException: createQuery is not valid without active transa

 
阅读更多
在使用hibernate3时老是报:org.hibernate.HibernateException: createQuery is not valid without active transaction
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:338)
at com.sun.proxy.$Proxy7.createQuery(Unknown Source)
at com.oyp.registration.dao.impl.UserDAOImpl.loadbyname(UserDAOImpl.java:18)
at com.oyp.registration.service.impl.UserManagerImpl.exists(UserManagerImpl.java:27)
at com.oyp.registration.service.UserManagerTest.testExists(UserManagerTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

网上说的解决方案:
很多时候我们使用hibernate的session时,都是让session在某一运行环境中保持其唯一。例如在同一线程内用同一个session,在同一方法内用同一session,这样我们就可以用session里面缓存好的数据。但,我想说的不是缓存,且听我一一道来。
        最近试用spring3.0.2+struts2.18+hibernate3.3.2学习搭建一个web项目,出现了一个相当郁闷的问题。就是我明明配置好了spring管理hibernate事务了,当我在dao中执行hibernate的方法时,如save,delete,update,createQuery,总是说不能在没有活动的事务中执行(org.hibernate.HibernateException: createSQLQuery is not valid without active transaction)。立马上google查,一无所获。曾几度怀疑是否配置写出了,dao或service写错了,改来改去的依旧存在问题。当时相当郁闷啊,想啊,你spring不是帮我管理事务么?你不自动开启事务啊,还要我手动开启啊。立马查spring文档,从中文到英文,没发现什么有参考价值的线索,真是相当的打击。代码乱改一通,发现用spring的hibernatetemplate来进行数据操作又正常无比。不死心的去查了hibernate的doc,一个不留神给哥发现了一个冗长的配置属性:hibernate.current_session_context_class。心里巨爽无比,就是你丫啦。小样的,哥把你灭了。
        hibernate.current_session_context_class是做什么用的呢?通俗点来讲,就是配置session绑定到某一运行环境,例如从同一个线程中用getCurrentSession()取得的session都是同一个,当前没有session就自动创建一个返回给你丫用。问题就出在这里了,官方文档如下说:
        使用 hibernate 的大多数应用程序需要某种形式的“上下文相关的”会话,特定的会话在整个特
定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这种“上下文”下一个定义通常是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在 3.0 版本之前,使用 Hibernate 的程序要么采用自行编写的基于 ThreadLocal 的上下文会话,要么采用HibernateUtil 这样的辅助类,要么采用第三方框架(比如 spring 或 Pico),它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关的会话。从 3.0.1 版本开始,Hibernate 增加了SessionFactory.getCurrentSession() 方法。一开始,它假定了采用 JTA 事务,JTA 事务定义了当前 session 的范围和上下文(scope 和 context)。因为有好几个独立的 JTA TransactionManager 实现稳定可用,不论是否被部署到一个 J2EE 容器中,
大多数(假若不是所有的)应用程序都应该采用 JTA 事务管理。基于这一点,采用 JTA 的上下文相关的会话可以满足你一切需要。

        再来看我的配置,讲hibernate.current_session_context_class的值设成thread。按我简单的理解就是将getCurrentSession()返回的session绑定到当前运行线程中。比较专业的说法是此session的上下文是thread,但不是spring已经托管的那个Session对象。再用哥那大腿想了几下,瞬间了解了一些。所以获取的session是在spring代理的上下文之外的的当前线程之中,所以此session并非事务管理器代理的那个session,不会自动开启事务。根据官方提示:第三方框架提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关的会话的管理,所以把hibernate.current_session_context_class设置删除了,一切又回到当初风平浪静的日子了。
参考http://justsee.iteye.com/blog/1061576,终于了解这个问题的前因后果。摘录如下:

在ssh2中的sessionFactory配置文件中应将hibernate.current_session_context_class设为org.springframework.orm.hibernate3.SpringSessionContext(默认为此值),并应用spring管理事务。
如果为<prop key="hibernate.current_session_context_class">thread</prop> 则会报异常,
原因还是spring中hibernate.current_session_context_class的问题
在spring的类LocalSessionFactoryBean源码,方法buildSessionFactory中将hibernate.current_session_context_class设为org.springframework.orm.hibernate3.SpringSessionContext

但是我并没有使用spring,刚开始还以为是我使用web项目导致重新开始了一个线程,sessionFactory获取的那个线程与当前线程不是同一个,所以获取不到actice 的transaction.但我直接使用马士兵老是的代码运行程序又没问题,这下我知道肯定是我的代码出了问题,初看一下又发现不了,后来无奈只有重新新建一个项目,然后一个源文件一个源文件的替换与对比。发现原来我使用session的时候没加上session.begintransaction。悲剧一场,好在问题最终被定位出来了,解决了就好了!
分享到:
评论

相关推荐

    org.hibernate.HibernateException: No Hibernate Session bound to thread

    No Hibernate Session bound to thread,没有绑定线程解决办法,找了好久才找到的

    解决SpringDataJPA报错:org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null w

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/...

    HIbernate4.3.6整合c3p0所需jar

    Caused by: org.hibernate.HibernateException: Could not instantiate connection provider [org.hibernate.connection.C3P0ConnectionProvider] at org.hibernate.engine.jdbc.connections.internal....

    Hibernate+Proxool配置

    由于项目需求的需要,我们引入了连接池。...我们采用了Hibernate,所以可以考虑hibernate自带的连接池机制,但是发现效率不高,而且Hibernate也推荐使用c3p0或Proxool连接池,在我们的项目中采用了Proxool

    Hibernate3技术精辟详解

    Hibernate3技术精辟详解 Hibernate3 Hibernate3详解,看过就知道Hibernate3怎么配置和应用

    Spring4.0+Hibernate4.0+Struts2.3整合案例

    2、报错:org.hibernate.HibernateException: No Session found for current thread 意思是必须在transcation.isActive()条件下才能执行, 可以解决办法是:当方法不需要事务支持的时候,使用 Session ...

    spring_MVC源码

    18. class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt; 19. &lt;property name="dataSource" ref="dataSource" /&gt; 20. &lt;property name="hibernateProperties"&gt; 21. &lt;props&gt; 22...

    J2EE利用Hibernate采用B/S架构网页设计

    import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current ...

    Mysql数据库从5.6.28版本升到8.0.11版本部署项目时遇到的问题及解决方法

    1.Caused by: org.hibernate.HibernateException: Connection cannot be null when ‘hibernate.dialect’ not set 报错就配置吧 启动项目不报错了,但是访问项目报错了 2.访问报错...

    深入浅出Hibernate中文版 part1

    6.8 HibernateException,Checked 6.9 Template/Callback 简化业务方法 6.10 版面:一棵自身循环的树 6.11 版面与帖子:Master/Detail 主从关系 6.12 帖子树及其分页 6.13 与Web层交互 6.14 帖子的多形扩展:...

    jsp Hibernate入门教程第1/3页

    例如: 代码如下:HibernateTest.java ... public class HibernateTest { public static void main(String[] args) throws HibernateException { SessionFactory sessionFactory = new Configuration().configure().bui

    深入浅出Hibernate中文版 part2

    6.8 HibernateException,Checked 6.9 Template/Callback 简化业务方法 6.10 版面:一棵自身循环的树 6.11 版面与帖子:Master/Detail 主从关系 6.12 帖子树及其分页 6.13 与Web层交互 6.14 帖子的多形扩展:...

    hibernate的事务核并发

    hibernate详细解析.pdf文档,所有的都有。。

    struts hibernate spring 搞定分布式事务

    public void executeTransactionBySQL() throws HibernateException { TestJTAByOracleVo vo1=new TestJTAByOracleVo(); vo1.setName("3333333"); HibernateByOracleDAO.addByOracle(vo1); ...

    用户管理系统

    Query query=session.createQuery(hql) ; query.setString(0, u.getUsername()); query.setString(1, u.getUserpass()); query.setInteger(2, u.getUserright()); List&lt;User&gt; list=query.list(); if...

    新闻发布系统

    public List&lt;News&gt; doInHibernate(Session session) throws HibernateException,SQLException { List&lt;News&gt; list = null; Query query = session.createQuery("from News order by id desc"); query....

    数据库课程设计题目与例子

    public void deleteUsers(Users users) throws HibernateException { Session session = HibSessionFactory.currentSession(); Transaction tx = session.beginTransaction(); session.delete(users); tx....

Global site tag (gtag.js) - Google Analytics