`

saveOrUpdate is not valid without active transaction

 
阅读更多

在使用Spring+Hibernate的框架时,在applicationContext.xml中配置了如下的代码片段:

 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref local="dataSource"/>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">${hibernate.dialect}</prop>

<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>

<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>

<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>

<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>

<!-- 绑定会话到当前线程 -->

<prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop> 

</props>

</property>

<property name="mappingLocations">

<list>

<value>classpath:/com/changetech/model/*.hbm.xml</value>

</list>

</property>

</bean>


在调用Dao(是使用声明式事务管理@Transactional注解来进行配置的)层时,

 

@Transactional

public void saveOrUpdate(T t)

{

getSession().saveOrUpdate(t);

}

 

出现以下的错误:

 

org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction

at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:338)

at $Proxy23.saveOrUpdate(Unknown Source)

at com.changetech.dao.impl.BaseDao.saveOrUpdate(BaseDao.java:49)

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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)

at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)

at $Proxy15.saveOrUpdate(Unknown Source)

at com.changetech.service.impl.BaseService.saveOrUpdate(BaseService.java:22)

at com.changetech.client.MultiThreadServiceTest.sampleTest(MultiThreadServiceTest.java:51)

at com.changetech.client.MultiThreadServiceTest$ThreadB.runTest(MultiThreadServiceTest.java:66)

at net.sourceforge.groboutils.junit.v1.TestRunnable.run(TestRunnable.java:154)

at java.lang.Thread.run(Thread.java:619)

 

经过在网上查找原因,说是Hibernate源码里做了一些修改,说是,hibernate里的所有操作(包括get\load\delete\list\saveOrUpdate等)都必须在transcation.isActive()条件下才可以执行,否则就会出现上述的错误。

 

<prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop> 

如果把这句话去掉之后(Hibernate就开始利用Spring的事务管理),此错误就消失,目前还不知道是为什么。

但是对于spring如何默认打开Transaction还不是很清楚。

 

外部连接:

 

If you use spring 2.5 as a drop in replacement @Transactional isn't working any more.
They HibernateSession you get through a currentSession() has no active transaction and result in the following stack trace

Exception in thread "main" org.hibernate.HibernateException: createSQLQuery is not valid without active transaction
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
at $Proxy7.createSQLQuery(Unknown Source)
at ag.pinguin.myservice.impl.MyService.doSomething(MyService.java:30)
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:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy5.doSomething(Unknown Source)
at test.SpringTestMain.main(SpringTestMain.java:16)

With spring 2.0.7 the exact same code/config works fine

As of Spring 2.5, Spring uses a custom CurrentSessionContext implementation plugged into Hibernate (requires Hibernate 3.1+). Previously, Spring created a special SessionFactory proxy (which also worked with Hibernate 3.0.)

 

Note that your hibernate.cfg.xml specifies

<property name="current_session_context_class">thread</property>

This overrides the default CurrentSessionContext (Spring's) with the standard Hibernate thread-local context. This leads to the failure that you see. Spring 2.5 simply respects your configuration there – in this case, wrong configuration that Spring 2.0 simply ignored. In any case: You shouldn't have specified that even when using Spring 2.0!


分享到:
评论

相关推荐

    Hibernate merge、update与saveOrUpdate方法的区别

    ### Hibernate merge、update与saveOrUpdate方法的区别 在Hibernate框架中,`merge`、`update`与`saveOrUpdate`这三个方法都是用于更新或保存实体对象到数据库中的,但它们之间存在着重要的区别,这些区别主要体现...

    save, saveOrUpdate, persist, merge, update 区别.docx

    在Java的持久化框架Hibernate中,管理对象与数据库之间的交互是通过一系列的方法完成的,其中包括`save()`, `saveOrUpdate()`, `persist()`, `merge()`, 和 `update()`。这些方法各有其特点和适用场景,理解它们的...

    hibernate 的saveOrUpdate

    `saveOrUpdate`是Hibernate提供的一种便捷方法,用于处理对象的保存或更新操作。在深入讲解`saveOrUpdate`之前,我们先理解一下Hibernate的基本概念。 在Hibernate中,实体类(Entity Class)代表数据库中的表,...

    05_传智播客hibernate教程_实体对象的三种状态与saveOrUpdate方法

    在Java的持久化框架Hibernate中,实体对象的状态管理和`saveOrUpdate`方法是核心概念,对于理解和有效使用Hibernate至关重要。在本教程中,我们将深入探讨实体对象的三种状态以及`saveOrUpdate`方法的工作原理。 ...

    HibernateTemplate.saveOrUpdate时出现\xE7\x84十六进制之类的字符串

    在使用HibernateTemplate的saveOrUpdate方法时,如果遇到类似`\xE7\x84`这样的十六进制字符串,通常这是由于字符编码不匹配导致的汉字乱码问题。这个问题主要涉及到数据库的字符集设置、应用程序的编码配置以及数据...

    Hibernate save() saveorupdate()的用法第1/2页

    ### Hibernate中的`save()`与`saveOrUpdate()`方法详解 #### 一、概述 在Java持久化框架Hibernate中,`save()`与`saveOrUpdate()`是非常重要的两个方法,它们用于处理对象的持久化操作。理解这两个方法的工作原理...

    hibernate get/load/saveOrUpdate/statistics

    博文链接:https://log-cd.iteye.com/blog/205166

    导入导出excel优化

    // 其他辅助方法,如readCellData、isValid、createEntity等 } ``` 以上代码仅作为简化示例,实际应用中需要根据具体需求进行调整和优化。在进行Excel导入导出优化时,应结合项目实际,选择合适的策略和技术,以...

    hibernateCRUD

    使用Hibernate进行数据插入,主要通过Session对象的save()或saveOrUpdate()方法实现。例如: ```java SessionFactory factory = Configuration().configure().buildSessionFactory(); Session session = factory....

    Hibernate入门示例.doc

    1. 增加(Insert):通过Session的`save()`或`saveOrUpdate()`方法将Java对象持久化到数据库。 ```java Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); ...

    hibernate框架下的增删改查

    在Hibernate中,增加数据通常是通过`Session`对象的`save()`或`saveOrUpdate()`方法完成的。首先,你需要创建一个Java实体类,这个类代表数据库中的表,并使用注解或XML配置来映射字段。例如,假设有一个`User`类: ...

    hibernate增删改

    在Hibernate中,增加数据主要通过Session对象的save()或saveOrUpdate()方法来实现。首先,我们需要创建一个实体类,该类对应数据库中的表,并用注解@Entity定义。然后,为实体类的属性添加对应的注解,如@Id用于标识...

    Hibernate映射集合属性List

    session.saveOrUpdate(newOrder); transaction.commit(); session.close(); ``` 5. **懒加载与级联操作:** 默认情况下,Hibernate使用懒加载策略,只有在访问集合属性时才会加载其内容,以提高性能。同时,...

    .net core + nhibernate 增删改查

    创建一个新的对象实例,设置其属性,然后通过会话的 `Save()` 或 `SaveOrUpdate()` 方法将其保存到数据库。 ```csharp using (var session = sessionFactory.OpenSession()) { using (var transaction = session....

    hibernate增删改查方法

    Transaction transaction = session.beginTransaction(); ``` - **执行查询** 使用`createQuery`方法创建查询,然后调用`list`方法执行查询并返回结果列表。 - **普通查询** ```java String hql = "from ...

    hibernate入门知识

    Transaction transaction = session.beginTransaction(); User user = new User(); user.setUsername("testUser"); session.save(user); transaction.commit(); session.close(); ``` 这里,`SessionFactory`负责...

    Hibernate-CRUD自用基础模板

    使用Hibernate进行对象创建时,首先需要实例化一个Java实体对象,设置其属性,然后调用`Session`的`save()`或`saveOrUpdate()`方法将其持久化到数据库。例如: ```java Session session = sessionFactory....

Global site tag (gtag.js) - Google Analytics