11 Replies Latest reply on Jan 3, 2012 7:11 AM by arorapo

    JBPM's persistence reusing existing connection

    ysh_fdez

      Hello, I'm trying to introduce a jBPM project successfully. We want to enable jBPM's persistence. The examples are intended to make a new connection to the database for jBPM. My application is using Hibernate already, and it creates the connection to the database. I can not accept two simultaneous connections, one of them just to jBPM. Ideally, jBPM reuses the existing connection.

       

      Specifically is it enough with the object org.hibernate.Session order to jBPM realice its operations persistence?

       

      I suppose that have a application with a database's connection and want to jBPM reuses the same connection, should be common. However, as the documentation and examples I see, they create new connection to jBPM. It makes me wonder if I'm wrong concepts and considering incorrectly the need to share the connection.

       

      Can anyone give me any advice or warn me if I am engaged in a wrong way?

       

      Thank you for your wisdom

        • 1. Re: JBPM's persistence reusing existing connection
          gardellajp

          Hi Andres,

           

          You can configure a JTA datasource and reuse in your application and in jBPM. Then open the transaction with the transaction manager. In the official documentation you have an example.

           

          Juan

          • 2. Re: JBPM's persistence reusing existing connection
            salaboy21

            If you are using the JPAKnowledgeService, you need to send you current EntityManager instance as a parameter. As you may know already, jBPM5 uses JPA for the persistence mechanism, so you will need to find out how to create a new EntityManager and inject your current hibernate session in it. If you are planning to do that there is no need to use JTA, because you will just have one Hibernate Session and no syncronization is needed.

            Cheers

            • 3. Re: JBPM's persistence reusing existing connection
              gardellajp

              Hi Andres,

               

              See http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/architecture.html#architecture-ejb-persistctxpropagation.

               

              In a transaction-scoped container managed entity manager (common case in a Java EE environment), the JTA transaction propagation is the same as the persistence context resource propagation. In other words, container-managed transaction-scoped entity managers retrieved within a given JTA transaction all share the same persistence context. In Hibernate terms, this means all managers share the same session.

               

              So, you share session with JTA. Good things that jBPM JPAKnowledgeService use JTA to obtain transactions. JPAKnowledgeService javadoc says:

               

              Long term out of the box persistence of runtime state with JPA is possible with Drools & jBPM. You will need to configure a JPA entity manager (e.g. using hibernate) and have a JTA transaction manager (for development/testing purposes we recommend Bitronix as it's simple to setup and works embedded, but for production the use of JBoss Transactions is recommended).

               

              Correct me Mauricio if I don't understand well how manage persistent in jBPM with JPAKnowledgeService. Andrés you can refer to some database with JTA, see http://stackoverflow.com/questions/3217586/difference-between-a-jta-datasource-and-a-resource-local-datasource

               

              Juan

              1 of 1 people found this helpful
              • 4. Re: JBPM's persistence reusing existing connection
                salaboy21

                Juan, Thanks for the links and references. What I was saying is the fact that he has a Hibernate Session that will be wrapped by an Entity Manager. As you mention, all the entity managers will share the same session and that's why he will need to inject his current session inside an entity manager. If it's the same session and he is not using another transactional resource there will be just one transaction to commit or rollback so there will be no need to distributed transactions configurations.

                 

                Cheers

                1 of 1 people found this helpful
                • 5. Re: JBPM's persistence reusing existing connection
                  ysh_fdez

                  Thank very much Juan and Mauricio. Our applications create the connection as mode application managed entity manager. I'll trying to get a valid EntityManager from an instance of hibernate.Session. I will have the option to add a JTA transaction manager as plan B.

                   

                  We tested code that we have seen on the web, but as nothing has worked so I began to doubt.

                   

                  First way

                  http://community.jboss.org/thread/163990

                  Code

                  {code}org.hibernate.Session session = ...

                  Configuration cfg = new Configuration();

                  cfg.configure("/hibernate.cfg.xml");

                  EntityManagerFactory emf =

                             new EntityManagerFactoryImpl(session.getSessionFactory(), PersistenceUnitTransactionType.RESOURCE_LOCAL, true, null, cfg);

                  Environment env = KnowledgeBaseFactory.newEnvironment();

                  env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

                  StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

                  {code}

                  Error

                  {code}21/12/2011 08:38:10 [ERROR] (org.drools.persistence.SingleSessionCommandService)  - Could not commit session

                  java.lang.NullPointerException

                       at org.drools.persistence.jta.JtaTransactionManager.getStatus(JtaTransactionManager.java:205)

                  {code}

                   

                  Second way

                  http://docs.jboss.org/drools/release/5.3.0.CR1/drools-expert-docs/html/ch04.html#d0e2134

                  http://docs.jboss.org/jbpm/v5.1/javadocs/org/drools/runtime/StatefulKnowledgeSession.html

                  Code

                  {code}org.hibernate.Session session = ...

                  StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

                  ksession.setGlobal("hbnSession", session);

                  {code}

                  Error

                  {code}java.lang.RuntimeException: Unexpected global [hbnSession]

                       at org.drools.common.AbstractWorkingMemory.setGlobal(AbstractWorkingMemory.java:586)

                       at org.drools.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:332)

                  {code}

                   

                   

                  If I get the code that works I'll put it here.

                  Greetings

                  • 6. Re: JBPM's persistence reusing existing connection
                    salaboy21

                    The second option that you are trying makes no sense at all.

                    You should continue trying with the first one.. looking how to create a persistence unit and inject the current session that you have available.

                    I remember an article that explains how to create a new persistence unit using a persistence.xml file and then inject the session inside it once is created. You should try that option.

                     

                    Cheers

                    • 7. Re: JBPM's persistence reusing existing connection
                      ysh_fdez

                      The second option that you are trying makes no sense at all.

                      You should continue trying with the first one.. looking how to create a persistence unit and inject the current session that you have available.

                      Great, it's good know it I will discard the second option and continue with the first.

                       

                      I remember an article that explains how to create a new persistence unit using a persistence.xml file and then inject the session inside it once is created. You should try that option.

                      My partner is doing tested using a persistence.xml file but I think it's different that you mention. Coincidentally he gets the same error I get in my first choice.

                       

                      {code}

                      EntityManagerFactory emf = Persistence.createEntityManagerFactory( "manager" ); //manager name file persistence

                      Environment env = KnowledgeBaseFactory.newEnvironment();

                      env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

                      {code}

                       

                      persistence.xml

                      {code:xml}

                      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

                      <persistence xmlns="http://java.sun.com/xml/ns/persistence"

                                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                                   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"

                                   version="2.0">

                      <persistence-unit name="manager" transaction-type="RESOURCE_LOCAL">

                          <provider>org.hibernate.ejb.HibernatePersistence</provider>

                      <!--     <jta-data-source>jdbc/processInstanceDS</jta-data-source> -->     

                          <validation-mode>AUTO</validation-mode>

                          <properties>

                              <property name="hibernate.max_fetch_depth" value="3"/>    

                              <property name="hibernate.show_sql" value="true"/>

                              <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>

                              <property name="javax.persistence.jdbc.user" value="..."/>

                              <property name="javax.persistence.jdbc.password" value="..."/>

                              <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@..."/>

                              <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>

                              <property name="hibernate.max_fetch_depth" value="3"/>

                          </properties>

                        </persistence-unit>

                      </persistence>

                      {code}

                       

                      Greetings

                      • 8. Re: JBPM's persistence reusing existing connection
                        salaboy21

                        Try removing the hibernate properties and then inject the session to the entity manager. In the code that you paste there is no relationship with your existing hibernate session.

                        Cheers

                        • 9. Re: JBPM's persistence reusing existing connection
                          ysh_fdez

                          The error I get is the same as described in this issues: https://issues.jboss.org/browse/JBPM-3282

                           

                          org.drools.persistence.jta.JtaTransactionManager is always used by default, with or without specify JTA. In fact, the exception occurs in that class, in the method getStatus.

                           

                          In the last two messages in this thread, Marco Rietveld justified because jBPM need JTA: http://community.jboss.org/thread/168840

                           

                          The author of the issue and thread, Marco Piraccini, has found a drools's issue for asked compatibility without JTA, but it is marked as "wont'fix."

                          https://issues.jboss.org/browse/JBRULES-2289

                           

                          Everything indicates that we need JTA if we want to use jBPM.

                           

                          Greetings

                          • 10. Re: JBPM's persistence reusing existing connection
                            gardellajp

                            Hi Andrés,

                             

                            > Everything indicates that we need JTA if we want to use jBPM.

                             

                            I think this requirement is related to JPAKnowledgeService, no to jBPM at all.

                             

                            Juan

                            • 11. Re: JBPM's persistence reusing existing connection
                              arorapo

                              Hi

                               

                              I am trying to integrate JBPM5(5.1.0.Final) with Sybase.

                              so, I have picked persistence.xml  and copied it in meta-inf directory of my application. now when I try to run below code.

                               

                                          EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa" );

                                          Environment env = KnowledgeBaseFactory.newEnvironment();

                                          env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

                                          env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());   

                                          ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

                              I got mentioned exception while creating ksession

                               

                              Caused by: java.lang.NullPointerException

                                  at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:138)

                              It comes up at below line in SingleSessionCommandService.java

                              ((InternalKnowledgeRuntime) ksession).setId( this.sessionInfo.getId() );

                              as this.sessionInfo.getId() is returning null.

                               

                              My persistence.xml has below contents

                              ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                              <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

                              <persistence version="1.0"

                                  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

                                                               http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd

                                                               http://java.sun.com/xml/ns/persistence/orm

                                                               http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"

                                  xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                                  xmlns="http://java.sun.com/xml/ns/persistence">

                               

                                  <persistence-unit name="org.jbpm.persistence.jpa" transaction-type="RESOURCE_LOCAL">

                                      <provider>org.hibernate.ejb.HibernatePersistence</provider>

                                      <!--<jta-data-source>java:/jdbc/testDS1</jta-data-source> mapping-file>META-INF/JBPMorm.xml</mapping-file -->

                                      <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>

                                      <class>org.drools.persistence.info.SessionInfo</class>

                                      <class>org.drools.persistence.info.WorkItemInfo</class>

                                      <properties>

                                          <property name="connection.driver_class" value="com.sybase.jdbc2.jdbc.SybDriver" />

                                          <property name="connection.url" value="<sybase.url>" />

                                          <property name="hibernate.dialect" value="org.hibernate.dialect.SybaseDialect" />

                                          <property name="connection.username" value="<username>" />

                                          <property name="connection.password" value="<password>" />

                                          <property name="hibernate.max_fetch_depth" value="3" />

                                          <property name="hibernate.hbm2ddl.auto" value="create" />

                                          <property name="hibernate.show_sql" value="true" />

                                      </properties>

                                  </persistence-unit>

                               

                              </persistence>

                              ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                               

                              Please let me know if I am heading in right direction and your suggestions on the same.

                               

                              Cheers

                              Pooja