Transaction not created automatically even if @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) is used
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*
精彩评论