开发者

Transaction not created automatically even if @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) is used

开发者 https://www.devze.com 2023-01-27 19:22 出处:网络
I have such managed bean in my Java EE 6 app: @Named @RequestScoped @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

I have such managed bean in my Java EE 6 app:

@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";
    }
}

As far as I understand @TransactionAttribute, new transaction should be automatically created. But apparently it is not, because I am getting an exception: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction

My persistence unit has transaction-type="JTA" attribute. I开发者_Go百科'm using JBoss 6 cr1.


What you are trying to do is not exactly correct. What you defined is a plain CDI bean, which does not natively supports the @TransactionAttribute annotation. This annotation is for use with an EJB bean, which you'll get by using the @Stateless annotation.

Note that in this case you'll don't necessarily need to use the TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotation. By default you are already getting TransactionAttributeType.REQUIRES when annotating your bean with @Stateless, which in most cases is what you want.


@TransactionAttribute is an EJB annotation. I don't believe the CDI container provides transaction management like the EJB container does.

One solution for your case would be to put the database access functionality into a stateless EJB and inject that into RegistrationBean. That being said, you don't need to specify TransactionAttributeType.REQUIRES_NEW in order to get automatic transaction handling. The implicit default, REQUIRES, should suffice unless you are planning on calling the EJB method from method running another transaction, and you want the called method to run in a separate transaction from the original.


By default, CDI does not support container managed transactions. However, using the Seam 3 Persistence module, you can add CMT support to your application.

The Seam Persistence documentation is here --> Link

Firstly, add the Seam Persistence jars to your project:

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

Next, enable declarative transaction management in your 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>

Now, according to the documentation, you should be able to use the @TransactionAttribute annotations with your managed bean like you would with an EJB, however, I couldn't get that to work. Instead, however, you can use the @Transactional annotation on your class or method. This is the Seam Persistence equivalent and works fine.

Hope this helps. Any questions, just ask.


TransactionAttributeType.REQUIRE*D*

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号