Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JEE7: Do EJB and CDI beans support container-managed transactions?

Tags:

Java EE7 consists of a bunch of "bean" definitions:

  • Managed Beans 1.0 (JSR-316 / JSR-250)
  • Dependency Injection for Java 1.0 (JSR-330)
  • CDI 1.1 (JSR-346)
  • JSF Managed Beans 2.2 (JSR-344)
  • EJB 3.2 (JSR-345)

In order to get rid of the chaos in my mind, I studies several articles of "when to use which bean type". One of the pros for EJB seems to be that they alone support declarative container-managed transactions (the famous transaction annotations). I'm not sure, though, if this is correct. Can anyone approve this?

Meanwhile, I came up with a simple demo application to check if this was actually true. I just defined a CDI bean (not an EJB - it has no class level annotations) as follows, based on this snippet:

public class CdiBean {
    @Resource
    TransactionSynchronizationRegistry tsr;

    @Transactional(Transactional.TxType.REQUIRED)
    public boolean isTransactional() {
        return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
    }
}

Now, the outcome on GlassFish 4.0 is that this method actually returns true, which, according to my inquiries, is not working as expected. I did expect the container to ignore the @Transactional annotation on a CDI bean method, or to even throw an exception. I use a freshly-installed GlassFish 4 server, so there are no interferences.

So my question is really:

  • Which bean types do actually support container-managed transactions?
  • Just for the sake of curiosity, how could I test it with a simple demo application if the code above is wrong?

(BTW: Someone described a similar problem here, but its solution does not apply to my case.

like image 222
SputNick Avatar asked Jul 24 '13 15:07

SputNick


People also ask

What is CDI and EJB?

The "C" in CDI is the main difference between EJB beans and managed CDI beans. CDI-managed beans are contextual and EJB beans are not. Managed beans in CDI live in well-defined scope. They are created and destroyed on demand by the container.

What are CDI managed beans?

A CDI bean is a POJO, plain old java object, that has been automatically instantiated by the CDI container, and is injected into all, and any qualifying injection points in the application. The CDI container initiates the bean discovery process during deployment.

What is container managed transaction?

Container managed transactions are considered the place where the container (JEE Server) controls the boundaries of the transactions, when to begin, when to commit or to rollback.

What is Bean-managed transaction?

In a bean-managed transaction, the code in the session or message-driven bean explicitly marks the boundaries of the transaction. An entity bean cannot have bean-managed transactions; it must use container-managed transactions instead.


2 Answers

Until Java EE 7 only EJB was transactional and the @Transactional annotation didn't exist.

Since Java EE 7 and JTA 1.2 you can use transactional interceptor in CDI with @Transactional annotation.

To answer your question about the best type of bean to use, the answer is CDI by default.

CDI beans are lighter than EJB and support a lot of feature (including being an EJB) and is activated by default (when you add beans.xml file to your app). Since Java EE 6 @Inject supersede @EJB. Even if you use remote EJBs (feature not existing in CDI) the best practice suggest that you @EJB once to inject remote EJB and a CDI producer to expose it as a CDI bean

public class Resources {

    @EJB
    @Produces
    MyRemoteEJB ejb;

}

The same is suggested for Java EE resources

public class Resources2 {

    @PersistenceContext
    @Produces
    EntityManager em;

}

These producers will be used later

public class MyBean {

    @Inject
    MyRemoteEJB bean;

    @Inject
    EntityManager em;

}

EJB continue to make sense for certain services they include like JMS or Asynchronous treatment, but you'll use them as CDI bean.

like image 98
Antoine Sabot-Durand Avatar answered Oct 01 '22 18:10

Antoine Sabot-Durand


The javadoc of Transactional says:

The javax.transaction.Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.

So, your assumptions are wrong. EJBs, until Java EE 6, were the only kinds of components to support declarative transactions. The Transactional annotation has precisely been introduced in Java EE 7 to make non-EJB, managed CDI beans transactional.

like image 38
JB Nizet Avatar answered Oct 01 '22 16:10

JB Nizet