2010-11-28 3 views
0

у меня есть такой управляемый компонент в моей Java EE 6 приложений:сделка не создается автоматически, даже если @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) используется

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

ответ

1

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

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

4

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

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

1

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

документация Шов Постоянство здесь ->Link

Во-первых, добавьте банки Шов персистенции к вашему проекту:

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

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

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