users@ejb-spec.java.net

[ejb-spec users] Clarification needed regarding the use of Extended EntityManager outside Stateful bean

From: <donatas.ciuksys_at_mif.vu.lt>
Date: Thu, 1 Nov 2012 13:19:44 +0000 (GMT)

Dear EJB experts,

By introducing @ConversationScoped annotation, CDI specification
sparkled interest for use of extended PersistenceContext - combining
@Stateful @ConversationScoped session bean with extended
PersistenceContext we are able to implement wizards, eshop checkout
processes and similar "conversation typed" use-cases. Introduction of
UNSYNCHRONIZED PersistenceContexts in future JPA 2.1 specification
further builds on this.

Imagine your @ConversationScoped @Stateful session bean (declaring
@PersistenceContext(type=EXTENDED) ) gets really big and complex, and
you'd like to split it to several beans (just to follow OO
coupling/cohession best practices). As a result, wizard like use-case
is now implemented not in one, but in several cooperating session
beans. Of course, we want all them to use the same instance of
EntityManager, created by the bean annotated with @ConversationScoped
(and controlling the life-cycle of this EntityManager). I identified
two possible implementations:

1. "Propagated extended EntityManager" - one Facade @ConversationScoped
@Stateful bean delegating business logic to other beans.
@ConversationScoped beans governs the conversation (but does not have
business logic), and declares @PersistenceContext(EXTENDED). As it
calls other beans, EntityManager gets propagated/inherited, and all
cooperating beans are using one and the same instance of EM.

2. "Injected extended EntityManager" - instead of propagation
mechanism, CDI producers and injection facility is being used. This
would be an example (copied from [1]):

@ConversationScoped
@Stateful
public class ConversationManager {
  @PersistenceContext(type=PersistenceContextType.EXTENDED)
  private EntityManager em;

  @Produces
  public EntityManager getEntityManager() { return em; }
}

@Stateless
public class BusinessLogic1 {
  @Inject
  private EntityManager em;

  public List<SomeEntity> getEntitiesFromDB() { return
em.createQuery("Some JPA query").getResultList(); }
}

The second approach allows web layer to communicate directly with
BusinessLogic beans (approach No. 1 requires to call
@ConversationScoped @Stateful bean that would delegate the call to
business logic bean). Also it decouples BusinessLogic1 from
ConversationManager.

This second approach sparkled discussion in [2], that the use of
extended EntityManager outside its "home stateful bean" is not
documented anywhere (EJB/JPA/CDI) and thus is not required to be
supported by EJB implementations. My contra-argument was that similar
issue was actually fixed in GlassFish [1] and is working OK.
Additionally I was able to find this excerpt from JPA specification to
validate the approach No. 2: (JPA specification)

-----------------------------------------------
3.3 Persistence Context Lifetime
...
When an extended persistence context is used, the extended persistence
context exists from the time the
EntityManager instance is created until it is closed. This persistence
context might span multiple transactions
and non-transactional invocations of the EntityManager. A
container-managed extended persistence
context is enlisted in the current transaction when *the EntityManager
is invoked in the scope of
that transaction* or when the stateful session bean to which the
extended persistence context is bound is
invoked in the scope of that transaction.
-----------------------------------------------

It seems that the first clause in the last sentence presumes the case
when EntityManager was accessed somehow without accessing its "home
stateful" bean itself, though multiple interpretations are possible.

My question is following: is the approach No. 2 valid per EJB/JPA
specification? Could the use of extended EntityManager outside its
"home stateful" session bean explained in more detail in JPA/EJB
specifications?

Best wishes,
Donatas Ciuksys

[1] http://java.net/jira/browse/GLASSFISH-11805
[2] https://issues.apache.org/jira/browse/TOMEE-509