Транзакция не создается автоматически, даже если используется @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) - PullRequest
0 голосов
/ 28 ноября 2010

В моем приложении Java EE 6 есть такой управляемый компонент:

@Named
@RequestScoped
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class RegistrationBean implements Serializable {

    @PersistenceContext
    EntityManager em;

    public String doRegistration() {
        MyEntity entity = new MyEntity();
        em.persist(entity);
        return "view";
    }
}

Насколько я понимаю, @TransactionAttribute новая транзакция должна создаваться автоматически.Но, по-видимому, это не так, потому что я получаю исключение: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction

Мой блок персистентности имеет атрибут transaction-type="JTA".Я использую JBoss 6 cr1.

Ответы [ 4 ]

4 голосов
/ 28 ноября 2010

То, что вы пытаетесь сделать, не совсем правильно. То, что вы определили, является простым компонентом CDI, который изначально не поддерживает аннотацию @TransactionAttribute. Эта аннотация предназначена для использования с EJB-компонентом, который вы получите, используя аннотацию @Stateless.

Обратите внимание, что в этом случае вам не обязательно использовать аннотацию TransactionAttribute (TransactionAttributeType.REQUIRES_NEW). По умолчанию вы уже получаете TransactionAttributeType.REQUIRES при аннотировании вашего компонента с помощью @Stateless, что в большинстве случаев является тем, что вам нужно.

1 голос
/ 24 января 2011

По умолчанию CDI не поддерживает транзакции, управляемые контейнером.Однако, используя модуль Seam 3 Persistence, вы можете добавить поддержку CMT в свое приложение.

Документация по Seam Persistence находится здесь -> Ссылка

Сначала добавьтеСохранение шва в вашем проекте:

<dependency>
  <groupId>org.jboss.seam.persistence</groupId>
  <artifactId>seam-persistence-api</artifactId>
  <version>${seam.persistence.version}</version>
</dependency>

<dependency>
  <groupId>org.jboss.seam.persistence</groupId>
  <artifactId>seam-persistence-impl</artifactId>
  <version>${seam.persistence.version}</version>
</dependency>

<dependency>
  <groupId>org.jboss.seam.solder</groupId>
  <artifactId>seam-solder</artifactId>
  <version>${seam.solder.version}</version>
</dependency>

Затем включите декларативное управление транзакциями в вашем beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://docs.jboss.org/cdi/beans_1_0.xsd">

   <interceptors>
      <class>org.jboss.seam.persistence.transaction.TransactionInterceptor</class>
   </interceptors>
</beans>

Теперь, согласно документации, выЯ должен иметь возможность использовать аннотации @TransactionAttribute с вашим управляемым компонентом, как если бы вы использовали EJB, однако я не смог заставить это работать.Однако вместо этого вы можете использовать аннотацию @ Transactional для вашего класса или метода.Это эквивалент Стойкости шва и отлично работает.

Надеюсь, это поможет.Любые вопросы, просто спросите.

1 голос
/ 28 ноября 2010

@ TransactionAttribute является аннотацией EJB. Я не верю, что контейнер CDI обеспечивает управление транзакциями, как это делает контейнер EJB.

Одним из решений для вашего случая было бы поместить функциональность доступа к базе данных в EJB без сохранения состояния и вставить это в RegistrationBean. При этом вам не нужно указывать TransactionAttributeType.REQUIRES_NEW, чтобы получить автоматическую обработку транзакций. Неявного значения по умолчанию REQUIRES должно быть достаточно, если только вы не планируете вызывать метод EJB из метода, выполняющего другую транзакцию, и не хотите, чтобы вызываемый метод выполнялся в отдельной транзакции от оригинала.

0 голосов
/ 01 августа 2013

TransactionAttributeType.REQUIRE * D *

...