Thomas Setiabudi [https://community.jboss.org/people/thomas.setiabudi] created 
the discussion

"DroolsSpringJpaManager breaks when Database Server is restarted, how to handle 
it?"

To view the discussion, visit: https://community.jboss.org/message/832415#832415

--------------------------------------------------------------
Hi,

I use JBPM5.4.Final, and Drools-Spring 5.4.Final in a Web Application.
I create Stateful Knowledge Session and LocalTaskService in the Spring config 
file, they are created once for the rest of the web application life.

Everything works fine, until the Database Server, MS SQL Server 2008, is 
restarted.
Which then break the Stateful Knowledge Session and LocalTaskService.

After looking into the code, I found that when we declare Stateful Knowledge 
Session like this:

<drools-spring:ksession id="ksession1" type="stateful"
                    kbase="kbase1">
                    <drools-spring:configuration>
                              <drools-spring:jpa-persistence>
                                        <drools-spring:transaction-manager
                                                  ref="transactionManager" /> 
                                        <drools-spring:entity-manager-factory
                                                  ref="entityManagerFactory" />
                              </drools-spring:jpa-persistence>
                    </drools-spring:configuration>
          </drools-spring:ksession>



Eventhough we give it EntityManagerFactory, the code inside 
DroolsSpringJpaManager will try to get EntityManager just once
this is how the code looks inside 
org.drools.container.spring.beans.persistence.DroolsSpringJpaManager:
 
https://github.com/droolsjbpm/droolsjbpm-integration/blob/5.5.x/drools-container/drools-spring/src/main/java/org/drools/container/spring/beans/persistence/DroolsSpringJpaManager.java#L64
 
https://github.com/droolsjbpm/droolsjbpm-integration/blob/5.5.x/drools-container/drools-spring/src/main/java/org/drools/container/spring/beans/persistence/DroolsSpringJpaManager.java#L64
Look at the implementation of getApplicationScopedPersistenceContext starting 
from line 64

The problem with this implementation is EntityManagerFactory used exactly just 
one time to get an EntityManager, even when the database connection is no 
longer valid, it will still use the same EntityManager which will of course 
throw exception.

My question is, is it a bug? or I use these Stateful Knowledge Session Wrongly?


Currently, to keep my application running, I modified DroolsSpringJpaManager at 
getApplicationScopedPersistenceContext():
If the appScopedEntityManager is not null, then execute simple select query, 
when that query throws exception, that means its time to get new EntityManager 
from the EntityManagerFactory.
It may be an ugly fix, but thats why I need to clarify this issue.
here is the code:

public PersistenceContext getApplicationScopedPersistenceContext() {
                    boolean refreshEntityManager = false;
                    if (this.appScopedEntityManager != null) {
                              try {
                                        Query query = 
this.appScopedEntityManager
                                                            
.createQuery("SELECT 1 FROM Task WHERE id = 0 ");
                                        query.getResultList();
//                                        System.out.println("Query Result: " + 
String.valueOf(a));
                              } catch (Throwable e) {
//                                        System.out.println(e.getMessage());
                                        refreshEntityManager = true;
                              }
                    }
 
 
                    if (refreshEntityManager == true) {
//                              System.out.println("Refreshing EM....");
                              EntityManagerHolder emHolder = 
(EntityManagerHolder) TransactionSynchronizationManager
                                                  .getResource(this.emf);
                              this.appScopedEntityManager = 
this.emf.createEntityManager();
                              emHolder = new 
EntityManagerHolder(this.appScopedEntityManager);
                              internalAppScopedEntityManager = true;
                              
this.env.set(EnvironmentName.APP_SCOPED_ENTITY_MANAGER,
                                                  emHolder.getEntityManager());
//                              System.out.println("Done Refreshing EM....");
                    } else {
                              if (this.appScopedEntityManager == null) {
                                        // Use the App scoped EntityManager if 
the user has provided it,
                                        // and
                                        // it is open.
                                        this.appScopedEntityManager = 
(EntityManager) this.env
                                                            
.get(EnvironmentName.APP_SCOPED_ENTITY_MANAGER);
                                        if (this.appScopedEntityManager != null
                                                            && 
!this.appScopedEntityManager.isOpen()) {
                                                  throw new RuntimeException(
                                                                      "Provided 
APP_SCOPED_ENTITY_MANAGER is not open");
                                        }
 
 
                                        if (this.appScopedEntityManager == 
null) {
                                                  EntityManagerHolder emHolder 
= (EntityManagerHolder) TransactionSynchronizationManager
                                                                      
.getResource(this.emf);
                                                  if (emHolder == null) {
                                                            
this.appScopedEntityManager = this.emf
                                                                                
.createEntityManager();
                                                            emHolder = new 
EntityManagerHolder(
                                                                                
this.appScopedEntityManager);
                                                            
TransactionSynchronizationManager.bindResource(
                                                                                
this.emf, emHolder);
                                                            
internalAppScopedEntityManager = true;
                                                  } else {
                                                            
this.appScopedEntityManager = emHolder
                                                                                
.getEntityManager();
                                                  }
 
 
                                                  
this.env.set(EnvironmentName.APP_SCOPED_ENTITY_MANAGER,
                                                                      
emHolder.getEntityManager());
                                        }
                              }
                              if 
(TransactionSynchronizationManager.isActualTransactionActive()
                                                  && isJTA) {
                                        
this.appScopedEntityManager.joinTransaction();
                              }
                    }
 
 
                    return new 
JpaPersistenceContext(this.appScopedEntityManager, isJTA);
          }
 


Is it the correct way to do this?
Will this issue fixed in JBPM 6 ?

Any help is appreciated.

Regards,
Thomas Setiabudi


Note:
Attached server log that shows:
1. the error after database is restarted and I try to call start process on the 
ksession.
2. the error after the first error happen and I try to call start process on 
the ksession again.
--------------------------------------------------------------

Reply to this message by going to Community
[https://community.jboss.org/message/832415#832415]

Start a new discussion in jBPM at Community
[https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]

_______________________________________________
jboss-user mailing list
jboss-user@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to