Исключение JPA: для этого потока в настоящее время не активна транзакция, управляемая извне.

Исключение возникает при попытке вставить / обновить / удалить с помощью 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();
    }

} }

Журналы при запуске сервера
Запуск defaultServer (WebSphere Application Server 17.0.0.2/wlp-1.0.17.cl170220170523-1818) на IBM J9 VM, версия 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 , distributionMap-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

Исключение:
[ошибка] 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)


person funtoos    schedule 19.10.2017    source источник
comment
Почему бы вам не внедрить EntitiyManager с помощью @PersistenceContext в свой EJB? Если вы создадите его таким образом, то активной транзакции не будет.   -  person Simon Martinelli    schedule 19.10.2017
comment
Забыл упомянуть, я использую Spring (версия 4.1.6). Когда я аннотирую EnttyManger с помощью @PersistenceContext (unitName = BlueeCron). Получение исключения: вызвано: org.springframework.beans.factory.NoSuchBeanDefinitionException: bean-компонент с именем 'BlueeCron' не определен   -  person funtoos    schedule 19.10.2017
comment
Следует также отметить, что ваше приложение создает EntityManagerFactory с конструктором сеансового компонента без сохранения состояния в рамках усилий по созданию экземпляра EntityManager, но ссылка на созданный EntityManagerFactory теряется. Рекомендуется закрывать созданные вами экземпляры EntityManagerFactory (), чтобы предотвратить утечку ресурсов. Более того, использование EntityManager вашим сессионным компонентом без сохранения состояния является одноразовым, поскольку вы закрываете его в блоке finally. Следующий вызов этого сеансового компонента без сохранения состояния завершится ошибкой, потому что он попытается использовать закрытый EntityManager.   -  person FyreWyld    schedule 19.10.2017


Ответы (1)


Метод executeUpdate () требует, чтобы EntityManager был включен в транзакцию - в данном случае это глобальная транзакция, поскольку вы определили блок сохранения состояния JTA-типа. Вы выбрали метод начальной загрузки JSE в JPA (с использованием Persistence.createEntityManagerFactory () вместо инъекции через @PersistenceContext или @PersistenceUnit) - хотя я не поддерживаю использование метода начальной загрузки JSE в приложении EE, это не запрещено спец.

Однако я считаю, что проблема, с которой вы сталкиваетесь, заключается в том, что фактически у вас есть контекст персистентности, управляемый приложением, и, таким образом, ваше приложение отвечает за его включение в глобальную транзакцию (которая была бы запущена автоматически контейнером EJB. когда был вызван purgeBxTables (), поскольку я не вижу никаких аннотаций, объявляющих его как компонент сеанса управляемой транзакции), для чего требуется вызов EntityMangager.joinTransaction ().

EntityManager, управляемый приложением, будет автоматически присоединяться к глобальной транзакции только при первом создании EntityManager. Это не относится к вашему приложению, поскольку EntityManager создается при построении класса bean-компонента. В противном случае требуется вызов метода joinTransaction (), чтобы EntityManager присоединился к новой транзакции.

Ваше приложение должно будет вызвать em.joinTransaction (), прежде чем вы вызовете executeUpdate ().

Использование контекста сохраняемости, управляемого контейнером (с использованием @PersistenceContext для внедрения EntityManager), привело бы к тому, что EntityManager автоматически присоединился бы к глобальной транзакции (если вы не переопределите Transaction SynchronizationType по умолчанию на UNSYNCHRONIZED.)

person FyreWyld    schedule 19.10.2017
comment
Спасибо FyreWyld, он работает, когда я устанавливаю joinTransaction (). Теперь пытаюсь понять, как заставить его работать с помощью @PersistenceContext. - person funtoos; 19.10.2017