Java TransactionRequiredException执行更新/删除查询
您好,我正在spring和mongodb中使用HibernateJPA,我正在Glassfish-4.0上运行我的应用程序 我的服务级别是:Java TransactionRequiredException执行更新/删除查询,java,spring,hibernate,mongodb,jpa,Java,Spring,Hibernate,Mongodb,Jpa,您好,我正在spring和mongodb中使用HibernateJPA,我正在Glassfish-4.0上运行我的应用程序 我的服务级别是: @Component public class Test { @PersistenceContext EntityManager em; EntityManagerFactory emf; @Transactional public String persist(Details details) {
@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";
}
}
我的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>
我在代码中应用了一些更改,但它们没有效果。
谁能帮我把这件事弄清楚吗。
提前感谢。您不必担心开始和结束事务。您已经应用了@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";
}
编辑:问题似乎出在配置文件上。如果您使用的是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>
我不确定这是否会对你的情况有所帮助(也就是说,如果它仍然存在的话),但是,在浏览网页寻找类似的问题之后 我正在从持久性EntityManager创建一个本机查询以执行更新
Query query = entityManager.createNativeQuery(queryString);
我收到以下错误:
原因:javax.persistence.TransactionRequiredException:正在执行
更新/删除查询
许多解决方案建议在方法中添加@Transactional。
只是这样做并没有改变错误
一些解决方案建议向EntityManager请求EntityTransaction
,以便您可以调用begin并提交自己。
这会引发另一个错误:
原因:java.lang.IllegalStateException:不允许创建
共享EntityManager上的事务-使用Spring事务或EJB
改为CMT
然后我尝试了一种方法,大多数网站都说它是用于应用程序管理的实体管理器,而不是容器管理的(我相信Spring是这样的),那就是joinTransaction()
让@Transactional
修饰方法,然后在调用query.executeUpdate()
之前在EntityManager对象上调用joinTransaction()
,我的本机查询更新工作正常
我希望这能帮助其他遇到此问题的人。作为配置xml的一部分,很明显您将使用基于spring的事务。请确保用于@Transactional的导入是“org.springframework.transaction.annotation.Transactional”
在您的例子中,它可能是“javax.transaction.Transactional”直到我意识到我的方法被声明为
public final
,而不是public
,我才觉得什么都不管用。错误是由final
关键字引起的。删除它使错误消失。将@Transactional
从方法级移动到类级如何?
在类似的情况下也为我工作过,但我不能100%确定原因。我在使用Hibernate和Spring Jpa数据存储库时也遇到过同样的问题。我忘了将
@Transactional
放在spring数据存储库方法上在用
@Transactional
注释后,它对我有效。在我的情况下,我导入了错误的@Transactional
正确的答案是:
import org.springframework.transaction.annotation.Transactional;
而不是
import javax.transaction.Transactional;
在我的项目中将Spring 4与Hibernate 5集成并遇到此问题后,我发现通过将会话的获取方式从sessionFactory.openSession()
更改为sessionFactory.getCurrentSession()
,可以防止出现错误。
解决此错误的正确方法可能是继续为绑定事务使用同一个会话。opensession将始终创建一个新会话,它与前一个会话不同,后者持有已配置的事务。使用getCurrentSession并添加附加属性org.springframework.orm.hibernate5.SpringSessionContext
可以很好地用于我。我也犯了同样的错误
我刚刚在方法上添加了javax.transaction.Transactional的@Transactional注释
更新:
我建议使用
org.springframework.transaction.annotation.Transactional中Spring的@Transactional
注释代码>我遇到了相同的异常“TransactionRequiredException执行更新/删除查询”,但对我来说,原因是我在springapplicationContext.xml文件中创建了另一个bean,名为“transactionManager”引用“org.springframework.jms.connection.jmstransactionmanagerr”但是有另一个bean同名“transactionManager”引用“org.springframework.orm.jpa.JpaTransactionManager”。因此jmsbean超过了jpabean
重命名Jms的bean名称后,问题得到解决。我在Java SE中尝试在非JTA(即资源本地)实体管理器中运行批量更新查询时收到此异常。
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public int changepassword(String password, long mobile) {
// TODO Auto-generated method stub
session = factory.getCurrentSession();
Query query = session.createQuery("update User u set u.password='" + password + "' where u.mobile=" + mobile);
int result = query.executeUpdate();
return result;
}
add this code 200% it will work... might scenario is diff but write like this:)
我只是忘了把我的JPQL代码包装进去
em.getTransaction().begin();
及
只需在方法级别或类级别添加@Transactional。当您更新或删除记录时,您必须维护事务的持久性状态,并且@Transactional
管理此状态
和导入org.springframework.transaction.annotation.Transactional;
我在类级别添加
@Transactional注释和导入org.springframework.transaction.annotation.Transactional时遇到了相同的错误
然后我意识到,因为我使用的是hibernate查询,所以我导入了javax.persistence.query
,而不是import org.hibernate.query.query
。
em.getTransaction().commit();
entityManager.getTransaction().begin();
Query query = entityManager.createNativeQuery("UPDATE tunable_property SET tunable_property_value = :tunable_property_value WHERE tunable_property_name = :tunable_property_name");
query.setParameter("tunable_property_name", tunablePropertyEnum.eEnableJobManager.getName());
query.setParameter("tunable_property_value", tunable_property_value);
query.executeUpdate();
entityManager.getTransaction().commit();
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
@Modifying
public <S extends T> S save(S entity) {
Query q = entityManager.createNativeQuery(...);
q.setParameter...
q.executeUpdate();
return entity;
}
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class SearchRepo {
---
}
@EventListener(ContextRefreshedEvent.class)
@Transactional
public void methodName() {...}