Java TransactionRequiredException 执行更新/删除查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25821579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TransactionRequiredException Executing an update/delete query
提问by user41498
Hi I am using hibernate JPA with spring and mongodb and i am running my application on Glassfish-4.0.
嗨,我正在将 hibernate JPA 与 spring 和 mongodb 一起使用,并且我正在 Glassfish-4.0 上运行我的应用程序。
My service class is :
我的服务类是:
@Component
public class Test {
@PersistenceContext
EntityManager em;
EntityManagerFactory emf;
@Transactional
public String persist(Details details) {
details.getUsername();
details.getPassword();
Query query = em.createNativeQuery("db.details.find(username="+details.getUsername()+"&password="+details.getPassword());
em.getTransaction().begin();
em.persist(details);
em.getTransaction().commit();
em.flush();
em.clear();
em.close();
query.executeUpdate();
System.out.println("Sucessful!");
return "persist";
}
}
And my spring-context.xml is :
我的 spring-context.xml 是:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.javapapers.spring.mvc" />
<context:annotation-config />
<mvc:annotation-driven />
<tx:annotation-driven transaction-manager="txManager" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ogmTest"/>
</bean>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
</bean>
</beans>
I have applied some changes in the code but their is no effect. Can anyone please help me to sort out this. Thanks in advance.
我在代码中应用了一些更改,但它们没有效果。任何人都可以帮我解决这个问题。提前致谢。
回答by DeepInJava
You need not to worry about begin and end transaction. You have already apply @Transactional annotation, which internally open transaction when your method starts and ends when your method ends. So only required this is to persist your object in database.
您无需担心开始和结束事务。您已经应用了@Transactional 注释,它在您的方法开始时在内部打开事务,并在您的方法结束时结束。所以唯一需要的是将您的对象保存在数据库中。
@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public String persist(Details details){
details.getUsername();
details.getPassword();
Query query = em.createNativeQuery("db.details.find(username= "+details.getUsername()+"& password= "+details.getPassword());
em.persist(details);
System.out.println("Sucessful!");
return "persist";
}
EDIT : The problem seems to be with your configuration file. If you are using JPA then your configuration file should have below configuration
编辑:问题似乎出在您的配置文件上。如果您使用的是 JPA,那么您的配置文件应该具有以下配置
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="ORACLE" p:showSql="true" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceUnitName="YourProjectPU"
p:persistenceXmlLocation="classpath*:persistence.xml"
p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="persistenceProvider" ref="interceptorPersistenceProvider" />
</bean>
回答by Drew Corbin
I am not sure if this will help your situation (that is if it stills exists), however, after scouring the web for a similar issue.
我不确定这是否会对您的情况有所帮助(即如果它仍然存在),但是,在网上搜索类似问题之后。
I was creating a native query from a persistence EntityManager to perform an update.
我正在从持久性 EntityManager 创建本机查询以执行更新。
Query query = entityManager.createNativeQuery(queryString);
I was receiving the following error:
我收到以下错误:
caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
引起:javax.persistence.TransactionRequiredException:执行更新/删除查询
Many solutions suggest adding @Transactional to your method. Just doing this did not change the error.
许多解决方案建议将 @Transactional 添加到您的方法中。只是这样做并没有改变错误。
Some solutions suggest asking the EntityManager for a EntityTransaction
so that you can call begin and commit yourself.
This throws another error:
一些解决方案建议向 EntityManager 询问 a,EntityTransaction
以便您可以调用 begin 并自己提交。这会引发另一个错误:
caused by: java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
由以下原因引起:java.lang.IllegalStateException:不允许在共享 EntityManager 上创建事务 - 改用 Spring 事务或 EJB CMT
I then tried a method which most sites say is for use application managed entity managers and not container managed (which I believe Spring is) and that was joinTransaction()
.
然后我尝试了一种方法,大多数站点都说该方法用于使用应用程序管理的实体管理器而不是容器管理的(我相信 Spring 是),那就是joinTransaction()
.
Having @Transactional
decorating the method and then calling joinTransaction()
on EntityManager object just prior to calling query.executeUpdate()
and my native query update worked.
其@Transactional
装饰方法,然后调用joinTransaction()
调用EntityManager对象的前夕query.executeUpdate()
,我的本地查询更新工作。
I hope this helps someone else experiencing this issue.
我希望这可以帮助遇到此问题的其他人。
回答by Chetan Verma
as form the configuration xml it is clear that you are going to use spring based transaction. Please make sure that the import which you are using for @Transactional is "org.springframework.transaction.annotation.Transactional"
作为配置 xml 的形式,很明显您将使用基于 spring 的事务。请确保您用于@Transactional 的导入是“org.springframework.transaction.annotation.Transactional”
in your case it might be "javax.transaction.Transactional"
在你的情况下它可能是“javax.transaction.Transactional”
cheers
干杯
Chetan Verma
切坦维尔马
回答by Damir Olejar
Nothing seemed to work for me until I realized that my method was declared as public final
instead of just public
. The error was being caused by the final
keyword. Removing it made the error go away.
直到我意识到我的方法被声明为public final
而不仅仅是public
. 错误是由final
关键字引起的。删除它使错误消失。
回答by mvmn
How about moving @Transactional
from method to class level?
Worked for me in similar case, though I'm not 100% certain why.
如何@Transactional
从方法级别转移到类级别?在类似的情况下为我工作,尽管我不是 100% 确定为什么。
回答by Satya P
I have also faced same issue when I work with Hibernate and Spring Jpa Data Repository. I forgot to place @Transactional
on spring data repository method.
Its working for me after annotating with @Transactional
.
当我使用 Hibernate 和 Spring Jpa Data Repository 时,我也遇到了同样的问题。我忘了放置@Transactional
spring 数据存储库方法。
用@Transactional
.
回答by User-8017771
In my case, I had the wrong @Transactional
imported.
就我而言,我@Transactional
导入了错误的内容。
The correct one is:
正确的一种是:
import org.springframework.transaction.annotation.Transactional;
and not
而不是
import javax.transaction.Transactional;
回答by u6462197
After integrating Spring 4 with Hibernate 5 in my project and experiencing this problem, I found that I could prevent the error from appearing by changing the way of getting the session from sessionFactory.openSession()
to sessionFactory.getCurrentSession()
.
the proper way to work out this bug may be keep using the same session for the binding transaction.opensession will always create a new session which doesnt like the former one holding a transaction configed.using getCurrentSession and adding additional property <property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
works fine for me.
与Hibernate 5在我的项目集成Spring 4和遇到此问题后,我发现我可以防止错误,通过改变从获取会话的方式出现sessionFactory.openSession()
来sessionFactory.getCurrentSession()
。解决此错误的正确方法可能是继续为绑定事务使用相同的会话。opensession 将始终创建一个新会话,该会话与前一个持有事务配置的会话不同。使用 getCurrentSession 并添加其他属性<property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
对我来说很好用。
回答by Akshay Pethani
I Got the same error.
我得到了同样的错误。
I just added the @Transactionalannotation of javax.transaction.Transactionalon the method.
我只是在方法上添加了javax.transaction.Transactional的@Transactional注释。
回答by Abdullah
I faced the same exception "TransactionRequiredException Executing an update/delete query" but for me the reason was that I've created another bean in the spring applicationContext.xmlfile with the name "transactionManager" refering to "org.springframework.jms.connection.JmsTransactionManager" however there was another bean with the same name "transactionManager" refering to "org.springframework.orm.jpa.JpaTransactionManager". So the JPAbean is overriten by the JMSbean.
我遇到了同样的异常“ TransactionRequiredException Executing an update/delete query”,但对我来说,原因是我在 spring applicationContext.xml文件中创建了另一个名为“ transactionManager”的bean 指的是“ org.springframework.jms.connection .JmsTransactionManager”但是还有另一个 bean 具有相同的名称“ transactionManager”,指的是“ org.springframework.orm.jpa.JpaTransactionManager”。因此JPAbean 被JMSbean覆盖。
After renaming the bean name of the Jms, issue is resolved.
重命名 Jms 的 bean 名称后,问题已解决。