JPA异常:此线程当前没有外部管理的事务处于活动状态

时间:2017-10-19 15:35:49

标签: jpa websphere-liberty open-liberty

尝试使用executeUpdate()插入/更新/删除时抛出异常。选择查询工作正常。我已经尝试了堆栈溢出中提到的先前类似错误的所有建议。感谢任何指导。

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

Liberty服务器上启用的功能

<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>

Peristence.xml

<?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();
    }

} }

登录服务器启动
在IBM J9 VM上启动defaultServer(WebSphere Application Server 17.0.0.2/wlp-1.0.17.cl170220170523-1818),版本为pwa6480sr4fp5-20170421_01(SR4 FP5)(en_US)

[AUDIT] 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]。

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

[EL Info]:server:2017-10-19 10:23:13.215 - ServerSession(1864654006) - 检测到的服务器平台:org.eclipse.persistence.platform.server.was.WebSphere_Liberty_Platform。 S

例外:
[错误] javax.persistence.TransactionRequiredException: 异常描述:此线程当前没有外部管理的事务处于活动状态

[错误]在org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:94)

[错误]在org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.checkForTransaction(JTATransactionWrapper.java:54)

[错误]在org.eclipse.persistence.internal.jpa.EntityManagerImpl.checkForTransaction(EntityManagerImpl.java:2054)

[错误]在org.eclipse.persistence.internal.jpa.QueryImpl.executeUpdate(QueryImpl.java:291)

[错误]在com.bcbsnc.providers.dao.JPADao.purgeBxTables(JPADao.java:49)

1 个答案:

答案 0 :(得分:2)

executeUpdate()方法要求EntityManager与事务一起登记 - 在这种情况下是全局事务,因为您已经定义了JTA类型的持久性单元。您已选择使用JPA的JSE引导方法(使用Persistence.createEntityManagerFactory()而不是通过@PersistenceContext或@PersistenceUnit注入) - 虽然我不赞同在EE应用程序中使用JSE引导方法,它并没有被规范所禁止。

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

应用程序管理的EntityManager仅在首次创建EntityManager时自动加入全局事务。由于在构造bean类时创建了EntityManager,因此您的应用程序不是这种情况。否则,需要joinTransaction()方法调用,以便EntityManager加入新事务。

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

使用容器管理的持久化上下文(使用@PersistenceContext注入EntityManager)会使EntityManager自动加入全局事务(除非您将默认的Transaction SynchronizationType覆盖为UNSYNCHRONIZED。)