7
votes

The various partial descriptions of the subject have led me to suspect that BMT is strongly tied to an application-managed EntityManager (and the use of UserTransaction), and that CMT is strongly tied to a container-managed EntityManager.

Can anyone give (or point me to) a clear explanation of how exactly BMT/CMT relates to an application/container-managed EntityManager?

What combinations are allowed between transaction demarcation types and EntityManager management types?

  • Can I combine an application-managed EntityManager with CMT?
  • Can I combine a container-managed EntityManager with BMT?

Also, what is the relationship between UserTransaction and BMT/CMT vs application/container-managed EntityManager?

  • Can I use UserTransaction together with a container-managed EntityManager?
  • Does UserTransaction imply BMT and vice-versa?

EDIT: According to http://www.byteslounge.com/tutorials/container-vs-application-managed-entitymanager I can combine CMT/BMT with application/container-managed EntityManagers any way I like. That still leaves me with the question about the relationship between UserTransaction and BMT. Does one imply the other?

EDIT: contrary to the link posted above, http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html#bnbra claims that "Application-managed entity managers don’t automatically propagate the JTA transaction context. Such applications need to manually gain access to the JTA transaction manager and add transaction demarcation information when performing entity operations. The javax.transaction.UserTransaction interface defines methods to begin, commit, and roll back transactions. Inject an instance of UserTransaction by creating an instance variable annotated with @Resource". To me this sounds like "application-managed entity managers require bean managed transaction demarcations". Who is right? Oracle or Byteslounge?

1

1 Answers

4
votes

I will try to answer your questions, but there are more combinations of possible scenarios than you asked and that I will not try to answer them. In the following answer by container-managed I mean a JTA (not RESOURCE_LOCAL), transaction-scoped EntityManager (injected with PersistenceContextType.TRANSACTION instead of PersistenceContextType.EXTENDED)

Can I combine an application-managed EntityManager with CMT?

Yes, although this is not the usual use case. Basically the created entity manager will automatically join the current transaction. You can find an example of that in the JPA 2.0 specification,

7.7.1.1 Application-managed Persistence Context used in Stateless Session Bean

Can I combine a container-managed EntityManager with BMT?

Yes, I have seen unofficial examples and can be used in order to control ONLY when to begin/commit/rollback the transaction, as the injected EntityManager has automatically joined the transaction (i.e you do not control when the entitymanager joins the current JTA transaction). I have not seen any official examples (if you do, please provide them in the comments for completeness).

Can I use UserTransaction together with a container-managed EntityManager?

The question is not correctly put: with a UserTransaction you try to control the transaction and so, the correct question would be what combination is possible: UserTransaction with CMT (which does not make sense, as the transaction is controlled by the container) or with BMT (this is the typical legal case). And now you get the answer to your original question with the container-managed entitymanager (depending on CMT or BMT).

Does UserTransaction imply BMT and vice-versa?

I would say so, because in a CMT the JTA transaction is automatically began by the container.

To your last question: what you find on the webpage of Oracle seems incorrect to me. As I answered in your first question (with an official example), you can combine an application-managed entitymanager in a CMT (without an UserTransaction, please check the example in the specification).

Also, I found some other confusions in different places, and I think the official documentation is actually the JPA specification (along with the Java EE one). If there is something written there, that does not work, consider (and please do report!) it a bug.