gpt4 book ai didi

java - 为什么我的交易不活跃? javax.persistence.TransactionRequiredException : Executing an update/delete query

转载 作者:行者123 更新时间:2023-11-30 06:29:56 28 4
gpt4 key购买 nike

我有一个 Spring Web 服务 (Spring-WS) 应用程序,我正在尝试配置使用。我使用的堆栈如下

Spring 3
Spring-WS
JPA with Hibernate as the provider
JBoss 7.1*

应用配置如下:

持久性.xml

<persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/myDataSource</jta-data-source>
<non-jta-data-source>java:jboss/datasources/myDataSource</non-jta-data-source>
<class>myPackage.MyClass</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/>
<property name="hibernate.search.default.indexBase" value="./lucene/indexes"/>
<property name="hibernate.search.default.batch.merge_factor" value="10"/>
<property name="hibernate.search.default.batch.max_buffered_docs" value="10"/>
</properties>
</persistence-unit>

spring.xml - 实体管理器和事务管理器

<context:annotation-config/>

<context:component-scan base-package="com.mypackage"/>

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<!-- Live database entity and transaction managers -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="myDataSource">

<property name="persistenceUnitName" value="myPersistenceUnit" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />

<tx:annotation-driven transaction-manager="transactionManager" />

Web.xml - 加载上面的spring.xml文件

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/app-config.xml
/WEB-INF/spring.xml
/WEB-INF/spring-datasources.xml
</param-value>
</context-param>

Spring 数据源.xml

<jee:jndi-lookup id="myDataSource" jndi-name="java:jboss/datasources/myDataSource"/>

在我的 DAO 类中,我对 entityManager 有以下定义。

@PersistenceContext(type=PersistenceContextType.TRANSACTION, unitName="myPersistenceUnit")
protected EntityManager entityManager;

@Transactional
public void updateProduct(Product product) {

// Save the document to the database
update(product);
}

上面的更新方法只是通过调用 entityManager.merge(object); 来调用泛型方法

现在,当我测试上面的内容时,我发现如果我从数据库中读取它可以工作,但是如果我正在写入数据库(即创建或更新),它就不起作用。如果我尝试写入,我会得到以下异常:

javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)
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.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:310)
at $Proxy96.executeUpdate(Unknown Source)

我猜我可以从数据库中读取这意味着事务管理器的配置有问题。有什么想法吗?

编辑

好的,我刚刚重新阅读了上面的内容,发现最后一点有点错误。我在上面显示的异常仅在我使用 JPQL 使用 entityManager.createQuery 发出更新语句时才会发生。如果我尝试使用 entityManager.merge() 更新实体,实际上什么也没有发生。没有返回异常,但行没有更新。

最佳答案

当您将方法标记为 @Transactional 时,您指望的是 JTA,但正如 altanis 所述,您将持久性单元的事务类型定义为 RESOURCE_LOCAL,这不是 JTA。

1) 如果您想使用容器管理的事务然后更改事务类型,在 JBoss 中将您的数据源定义为 JTA 数据源并将非 jta 数据源更改为 jta 数据源

2) 如果您想管理自己的事务,请保持 persistence.xml 和数据源定义不变,但在任何持久化、合并、删除操作之前,通过调用 entitymanager.getTransaction().begin() 和在业务单元结束时,调用 entitymanager.getTransaction().commit() 或 entitymanager.getTransaction().rollback()。在这种情况下,由于您自己管理事务,因此似乎没有必要在 updateProduct() 中使用 @Transactional 启动 JTA 事务。

关于java - 为什么我的交易不活跃? javax.persistence.TransactionRequiredException : Executing an update/delete query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11016268/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com