cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti Engine and container-managed entity manager

lis
Champ in-the-making
Champ in-the-making
Is it possible to configure Activiti engine to use container-managed entity manager(em) when
I invoke Activiti API in EJB method?

@PersistenceContext(name = "persistence/SKO_EM")
private EntityManager em;

public testEJBMethod() {
//invoke Activiti API - I want Activiti engine to use em injected via annotation @PersistenceContext
// here Activiti engine can update some JPA variable in task listener, for example
….


//invoke some custom logic
TestEntity testEntity = em.find(..);
testEntity.setField(…);


}

Lis
12 REPLIES 12

frederikherema1
Star Contributor
Star Contributor
Did you read the topic about JPA in the userguide? You should check out the examples as well (JPAVariableTest I think it's called).

Activiti allows you to set the EntyManagerFactory to use when using JPA-entities as variable.

lis
Champ in-the-making
Champ in-the-making
Hi Frederik,

Activiti engine get Entity Manager  via call javax.persistence.Persistence.createEntityManagerFactory("unit").createEntityManager().
I examined sources of Activiti.

But when I use container-managed persistence in EJB, i dont need to get EM from factoty or create factory.
I use @PersistenceContext annotation.

@PersistenceContext(name = "persistence/SKO_EM")
private EntityManager em;

Suppose I invoke Activiti API in EJB method and engine update JPA variable internally (i created such process in designer).
Then I update same JPA variable in same EJB method outside engine API call. I am using Entity Manager getted from
annotation.

Problem: Activity Engine uses another Entity Manager. I dont see any ability to ask engine use my Entity manager. Engine always
call createEntityManager() and create new Entity Manager.

Lis

frederikherema1
Star Contributor
Star Contributor
Doesn't EJB provide entity-manager factories (proxies) who reuse the same EnitityManager instance, as long as the transaction is running in the same thread? (sorry, has been a while since I did EJB stuff Smiley Wink)

If not, I don't see another option than writing your own solution or suggest one to us that is more flexible (and not restricting) than the one we have now… But you saw the code for wiring in the JPA-stuff,  that's a good starting point.

lis
Champ in-the-making
Champ in-the-making
We are using WebSphere App Server 7.0.
Entity manager getted from annotation and via createEntityManager in the same thread differrent.
I created sample entity and invoked em.contains(sampleEntity) to check this.

May be this only in WAS container and some containers provide Entity Manager propagation feature
in the same thread.

frederikherema1
Star Contributor
Star Contributor
Than I'm affraid you're on your own Smiley Wink But hooking into custom Entity-manager lookup shouldn't be that hard, you can do it in your codebase. Take a look al org.activiti.engine.impl.variable.EntityManagerSession, EMSFactory, … etc. You can find examples on forum on how to plug your own sessions in activiti config…

lis
Champ in-the-making
Champ in-the-making
Solution for Container-Managed Entity Manager:

1) Do not use Persistence.createEntityManagerFactory("UNIT_NAME").createEntityManager();
2) If Entity manager injected in EJB with @PersistenceContext(name = "persistence/UNIT_NAME") private EntityManager em; annotation
EJB, than to find same entity manager in Activiti Engine code use next code:

  InitialContext ctx = new InitialContext();
  EntityManager em = (EntityManager) ctx
    .lookup("java:comp/env/persistence/UNIT_NAME");

I think best place for this lookup in EntityManagerSessionFactory.openSession() .


  public Session openSession() {
              InitialContext ctx = new InitialContext();
EntityManager entityManager = (EntityManager) ctx
    .lookup("java:comp/env/persistence/UNIT_NAME");
    return new EntityManagerSessionImpl(null, entityManager, handleTransactions, closeEntityManager);
  }

3) Set handleTransactions = false, closeEntityManager = false

Lis

frederikherema1
Star Contributor
Star Contributor
That look good, thanks for sharing!

lis
Champ in-the-making
Champ in-the-making
Is it possible to include this in future releases of ACTIVITI? I think It was good
to have configuration variable like ejbContainerManagedEM = true/false to switch
to another EM lookup method.

In current release (5.6) I need to do:

1) Create new impementation org.activiti.engine.impl.interceptor.SessionFactory and implement
EM lookup in openSession method().
2) Override initJPA() in ProcessEngineConfigurationImpl

protected void initJpa() {

   sessionFactories.put(EntityManagerSession.class,
     new MY_EntityManagerSessionFactory(jpaEntityManagerFactory,
       jpaHandleTransaction, jpaCloseEntityManager));
   VariableType jpaType = variableTypes
     .getVariableType(JPAEntityVariableType.TYPE_NAME);
   // Add JPA-type
   if (jpaType == null) {
    // We try adding the variable right before SerializableType, if
    // available
    int serializableIndex = variableTypes
      .getTypeIndex(SerializableType.TYPE_NAME);
    if (serializableIndex > -1) {
     variableTypes.addType(new JPAEntityVariableType(),
       serializableIndex);
    } else {
     variableTypes.addType(new JPAEntityVariableType());
    }
   }
}

Not very clear solution.

frederikherema1
Star Contributor
Star Contributor
You can plug in an alternative factory in your OWN configuration, not in activiti-code.

You suggest creating a parameter with the jndi-name of the entity-manager? (because this ofcourse depends on the environnement)

You can always contribute a patch of this kind of solution, if you want…