当前位置: 首页 > 知识库问答 >
问题:

JPA异常:该线程当前没有活动的外部管理事务

贲永思
2023-03-14

尝试使用executeUpdate()插入/update/delete时引发异常。Select query工作得很好。我已经尝试了以前在Stack-Overflow中提到的类似错误的所有建议。感谢任何指导。

环境:Websphere Liberty:17.0.0.2、Eclipselink 2.6.4、JPA 2.1

在Liberty server上启用的功能

<featureManager>
    <feature>adminCenter-1.0</feature>
    <feature>beanValidation-1.1</feature>
    <feature>cdi-1.2</feature>
    <feature>concurrent-1.0</feature>
    <feature>ejbLite-3.2</feature>
    <feature>el-3.0</feature>
    <feature>jsf-2.2</feature>
    <feature>jsp-2.3</feature>
    <feature>localConnector-1.0</feature>
    <feature>servlet-3.1</feature>
    <feature>jpa-2.1</feature>
    <!--The following features are available in Liberty base and above. -->
    <feature>jaxb-2.2</feature>
</featureManager>
<?xml version="1.0" encoding="UTF-8"?>
 <persistence version="2.1"
   xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
   http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="BlueeCron" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/BlueeUPMDataSource</jta-data-source>
    <mapping-file>META-INF/queries.xml</mapping-file>
    <class>com.bcbsnc.providers.models.BlueEReqst</class>
    <class>com.bcbsnc.providers.models.BlueERespn</class>
    <properties>
        <property name="eclipselink.logging.level" value="ALL" />
        <property name="eclipselink.logging.level.sql" value="FINE" />
        <property name="eclipselink.logging.parameters" value="true" />
    </properties>
</persistence-unit>
@Stateless
@Repository("emJPADao")
public class JPADao {

EntityManager entityManager = Persistence.createEntityManagerFactory("BlueeCron").createEntityManager();

public Integer purgeBxTables() {
    Integer rowsDeleted = 0;
    try {
        Integer noOfDays = Integer.parseInt(this.getConfigurationData("PurgeBXTablesPeriod"));
        rowsDeleted = entityManager.createNamedQuery("PURGE_BX_TABLES").setParameter("noOfDays", getTimeStamp(noOfDays, false)).executeUpdate();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        if(entityManager.isOpen())
            entityManager.close();
    }

[审核]CWWKF0012I:服务器安装了以下功能:[JSP-2.3、EJBLite-3.2、Servlet-3.1、JSF-2.2、BeanValidation-1.1、SSL-1.0、JNDI-1.0、JCA-1.7、JDBC-4.2、LocalConnector-1.0、AppSecurity-2.0、JAXRS-2.0、RESTConnector-1.0、EL-3.0、JAXRSClient-2.0、Concurrent-1.0、WMQJMSClient-2.0、JAXB-2.2、JSON-1.0、JPAContainer-2.1、AdminCenter-1.0、CDI-1.2、DistributedMap-1.0、JPA-2.1]。

[审核]CWWKF0011I:服务器defaultServer已准备好运行一个更智能的星球。

[EL信息]:服务器:2017-10-19 10:23:13.215--Serversession(1864654006)--检测到服务器平台:org.eclipse.persistence.platform.server.was.websphere_liberty_platform。S

异常:
[err]javax.persistence.TransactionRequiredException:异常描述:当前该线程没有活动的外部管理事务

[err]位于org.eclipse.persistence.internal.jpa.transaction.JTatransactionWrapper.ThrowCheckTransactionFailedException(JTatransactionWrapper.java:94)

[err]位于org.eclipse.persistence.internal.jpa.transaction.JTatransactionWrapper.CheckforTransaction(JTatransactionWrapper.java:54)

[err]位于org.eclipse.persistence.internal.jpa.EntityManagerImpl.CheckforTransaction(EntityManagerImpl.java:2054)

[err]位于org.eclipse.persistence.internal.jpa.queryimpl.executeUpdate(queryimpl.java:291)

[err]在com.bcbsnc.providers.dao.jpadao.purgeBXtables(jpadao.java:49)

共有1个答案

酆君墨
2023-03-14

executeUpdate()方法要求EntityManager注册一个事务-在本例中是一个全局事务,因为您已经定义了一个JTA类型的持久化单元。您已经选择使用JPA的JSE引导方法(使用persistence.createEntityManagerFactory(),而不是通过@persistenceContext或@persistenceUnit进行注入)--虽然我不赞成在EE应用程序中使用JSE引导方法,但规范不允许使用这种方法。

但是,我认为您遇到的问题是这样一个事实,即您在这里实际上拥有的是一个应用程序管理的持久化上下文,因此您的应用程序负责它与全局事务的登记(当调用purgeBxTables()时,EJB容器将自动启动全局事务,因为我没有看到任何注释将其声明为bean管理的事务会话bean),这需要调用entityMangager.joinTransaction()。

应用程序管理的EntityManager只有在首次创建EntityManager时才会自动加入全局事务。对于您的应用程序来说,情况并非如此,因为EntityManager是在构造bean类时创建的。否则,joinTransaction()方法调用是必需的,以便EntityManager加入一个新事务。

在调用executeUpdate()之前,应用程序需要调用em.jointransaction()。

使用容器管理的持久化上下文(使用@PersistenceContext注入EntityManager)将使EntityManager自动加入全局事务(除非您将默认事务SynchronizationType重写为Unsynchronized)

 类似资料: