13 Replies Latest reply on Jun 29, 2007 3:41 AM by slogger

    How can I split storage scheme JBPM and general?

    slogger

      How can I split storage scheme JBPM and general?
      I tried to create different DataSource (two confiqs *-ds.xml with local-tx-datasource), but I got issues.
      It is necessary for application to guarantee execution in single transaction (jbpm and general).
      RDBMS Oracle10g, JDK 1.5.8, JBoss 4.2.0, Jbpm-3.2
      What's the matter? Please, sorry my English.

      Jbpm is deployed as EAR, with config:

      ...
       <service name="persistence">
       <factory>
       <bean class="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory"/>
       <field name="isTransactionEnabled"><false/></field>
       </factory>
       </service>
       ...


      FIRST

      2007-06-20 10:01:35,625 WARN [org.hibernate.cfg.SettingsFactory] Could not obtain connection metadata
      org.jboss.util.NestedSQLException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57218c:1154:4677a2d0:3c70 status: ActionStatus.ABORT_ONLY >); - nested throwable: (org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57218c:1154:4677a2d0:3c70 status: ActionStatus.ABORT_ONLY >))
       at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:94)
       at org.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:69)
       at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:84)
       at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
       at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
       at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:91)
       at org.jbpm.persistence.jta.JtaDbPersistenceService.isCurrentJtaTransactionAvailable(JtaDbPersistenceService.java:37)
       at org.jbpm.persistence.jta.JtaDbPersistenceService.<init>(JtaDbPersistenceService.java:22)
       at org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory.openService(JtaDbPersistenceServiceFactory.java:17)
       at org.jbpm.svc.Services.getService(Services.java:141)
       at org.jbpm.svc.Services.getPersistenceService(Services.java:180)
       at org.jbpm.JbpmContext.getPersistenceService(JbpmContext.java:628)
       at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:569)
       at org.jbpm.JbpmContext.newProcessInstance(JbpmContext.java:408)
       at com.rfc.security.scheme.actions.ActionCreateDoc.doSomething(ActionCreateDoc.java:26)
       at com.rfc.security.scheme.actions.PAction.execute(PAction.java:30)
       at com.rfc.ejb.security.SecurityMgrBean.executeAction(SecurityMgrBean.java:73)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       ...
      Caused by: org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57218c:1154:4677a2d0:3c70 status: ActionStatus.ABORT_ONLY >)
       at org.jboss.resource.connectionmanager.TxConnectionManager.managedConnectionReconnected(TxConnectionManager.java:343)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2.reconnectManagedConnection(BaseConnectionManager2.java:518)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:399)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:842)
       at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:88)
       ... 49 more
      Caused by: javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: -3f57218c:1154:4677a2d0:3c70 status: ActionStatus.ABORT_ONLY >
       at org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener$TransactionSynchronization.checkEnlisted(TxConnectionManager.java:744)
       at org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener.enlist(TxConnectionManager.java:577)
       at org.jboss.resource.connectionmanager.TxConnectionManager.managedConnectionReconnected(TxConnectionManager.java:337)
       ... 53 more

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

      SECOND

      2007-06-20 10:01:38,843 ERROR [STDERR] org.hibernate.HibernateException: Unable to register cleanup Synchronization with TransactionManager
       at org.hibernate.context.JTASessionContext.currentSession(JTASessionContext.java:92)
       at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:544)
       at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:103)
       at org.jbpm.persistence.db.DbPersistenceService.getGraphSession(DbPersistenceService.java:334)
       at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:571)
       at org.jbpm.JbpmContext.newProcessInstance(JbpmContext.java:408)
       at com.rfc.security.scheme.actions.ActionCreateDoc.doSomething(ActionCreateDoc.java:26)
       at com.rfc.security.scheme.actions.PAction.execute(PAction.java:30)
       at com.rfc.ejb.security.SecurityMgrBean.executeAction(SecurityMgrBean.java:73)
       ...
      2007-06-20 10:01:38,921 ERROR [com.rfc.ejb.security.SecurityMgrBean] Unable to register cleanup Synchronization with TransactionManager
      org.hibernate.HibernateException: Unable to register cleanup Synchronization with TransactionManager
       at org.hibernate.context.JTASessionContext.currentSession(JTASessionContext.java:92)
       at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:544)
       at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:103)
       at org.jbpm.persistence.db.DbPersistenceService.getGraphSession(DbPersistenceService.java:334)
       at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:571)
       at org.jbpm.JbpmContext.newProcessInstance(JbpmContext.java:408)
       at com.rfc.security.scheme.actions.ActionCreateDoc.doSomething(ActionCreateDoc.java:26)
       at com.rfc.security.scheme.actions.PAction.execute(PAction.java:30)
       at com.rfc.ejb.security.SecurityMgrBean.executeAction(SecurityMgrBean.java:73)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       ...


      1-th config:
      ...
      <jndi-name>Oracle10jbpm</jndi-name>
      <connection-url>jdbc:oracle:thin:@192.168.222.116:1521:ora10utf</connection-url>
      <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
      <user-name>jbpm</user-name>
      ...

      2-th config:
      ...
      <jndi-name>Oracle10db</jndi-name>
      <connection-url>jdbc:oracle:thin:@192.168.222.116:1521:ora10utf</connection-url>
      <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
      <user-name>pilot</user-name>
      ...



        • 1. Re: How can I split storage scheme JBPM and general?

          It is not recommended to use two JNDI for the same physical database.

          Use different JNDI names for different databases and update your persistence configuration accordingly

          • 2. Re: How can I split storage scheme JBPM and general?
            slogger

             

            "fady.matar" wrote:
            It is not recommended to use two JNDI for the same physical database.

            Use different JNDI names for different databases and update your persistence configuration accordingly


            Hmmm... "not recommended"
            In that way, it is impossible just to split schemes? If it's possible, how can I do it?

            • 3. Sorry!
              slogger

              In any case, fady.matar thank you very much for your answer!

              • 4. Re: How can I split storage scheme JBPM and general?

                Are you using the web console or creating your own application from scratch? The configuration can be specified in different ways. Elaborate more so I can assist you in this.

                • 5. I created my own app
                  slogger

                  I created my own application.
                  Jbpm included to my ear with his console war.
                  In addition, ear consists of my ejbs (by EJB3 spec + hiber).
                  Thus, this ear has two hibernate.cfg.xml.
                  The first one is used for own mappings of business data.

                  • 6. Re: How can I split storage scheme JBPM and general?
                    mputz

                     

                    It is necessary for application to guarantee execution in single transaction (jbpm and general).


                    If you want to access the jBPM and the application data from within the same Hibernate session you could inject the Hibernate session into the jbpmContext (jbpmContext.setSession(s);).

                    This can be done by using the DbPersistenceServiceFactory. You would have to set the configuration parameter "isCurrentSessionEnabled" to true, which wouldn't close the Hibernate session on the jBPM side. You could continue to work within the current transaction and do the Hibernate clean up work at the end of the transaction.


                    • 7. Re: How can I split storage scheme JBPM and general?
                      slogger

                       

                      "mputz" wrote:
                      It is necessary for application to guarantee execution in single transaction (jbpm and general).


                      If you want to access the jBPM and the application data from within the same Hibernate session you could inject the Hibernate session into the jbpmContext (jbpmContext.setSession(s);).

                      This can be done by using the DbPersistenceServiceFactory. You would have to set the configuration parameter "isCurrentSessionEnabled" to true, which wouldn't close the Hibernate session on the jBPM side. You could continue to work within the current transaction and do the Hibernate clean up work at the end of the transaction.


                      Your offer means to store of all in single db scheme.
                      But expression "single transaction" is not means single db scheme.
                      I want to store jbpm data and business data in different schemes of Oracle DB.

                      • 8. Re: How can I split storage scheme JBPM and general?

                        fady.matar wrote:

                        It is not recommended to use two JNDI for the same physical database.


                        I'm no expert here, but I don't think this is exactly correct. Accessing different databases (schemas) in the same physical database using different JNDI names is perfectly fine, except perhaps for Hibernate. In fact, I think it's the ONLY way to do it within J2EE.

                        In slogger's case, he showed JNDI with different schemas (i.e., user-names):

                        1-th config:
                        ...
                        <jndi-name>Oracle10jbpm</jndi-name>
                        <connection-url>jdbc:oracle:thin:@192.168.222.116:1521:ora10utf</connection-url>
                        <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
                        <user-name>jbpm</user-name>
                        ...
                        
                        2-th config:
                        ...
                        <jndi-name>Oracle10db</jndi-name>
                        <connection-url>jdbc:oracle:thin:@192.168.222.116:1521:ora10utf</connection-url>
                        <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
                        <user-name>pilot</user-name>
                        


                        slogger,

                        I can't help much with the Hibernate issue, but my reading suggests that if you want coherent transactions across the two databases, you need to use the features of and <hibernate-mapping> elements to bind together the schemas. Look at the way the identity schemas are bound in to JBPM for starters, then note that <hibernate-mapping> has a "schema" attribute.

                        If you want independent transactions between the two contexts, you're on your own!

                        -Ed Staub


                        • 9. Re: How can I split storage scheme JBPM and general?
                          slogger

                           

                          "estaub" wrote:
                          fady.matar wrote:

                          It is not recommended to use two JNDI for the same physical database.


                          Look at the way the identity schemas are bound in to JBPM for starters, then note that <hibernate-mapping> has a "schema" attribute.

                          If you want independent transactions between the two contexts, you're on your own!

                          -Ed Staub


                          estaub, thank you for your answer!
                          I will play with "schema" attribute of hiber.cfg

                          • 10. Re: How can I split storage scheme JBPM and general?
                            copperschnack

                            Hi slogger,

                            we are getting close to what you want, but we are not there yet. We currently utilize two different Hibernate configuration files for EJB3 Entities (via persistence.xml) and JBPM (via jbpm.cfg.xml). When we tried to split up XA transaction enabled sessions with one Hibernate configuration only, we ran into strange issues (eg. JBPM-Tables being created in both schemas).

                            Here is a short summary of the configuration files are being used:

                            persistence.xml --> hibernate.ejb.cfg.xml
                            jbpm.cfg.xml --> hibernate.jbpm.cfg.xml

                            Here are the details for your reference:

                            persistence.xml:

                            <?xml version="1.0" encoding="UTF-8"?>
                            <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             version="1.0"
                             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
                             <persistence-unit name="VacationPU" transaction-type="JTA">
                             <provider>org.hibernate.ejb.HibernatePersistence</provider>
                             <jta-data-source>jdbc/VACATION_TEST</jta-data-source>
                             <properties>
                             <property name="hibernate.ejb.cfgfile" value="hibernate.ejb.cfg.xml"/>
                             </properties>
                             </persistence-unit>
                            </persistence>



                            jbpm.cfg.xml
                            <jbpm-configuration>
                            
                             <!--
                             The default configurations can be found in org/jbpm/default.jbpm.cfg.xml
                             Those configurations can be overwritten by putting this file called
                             jbpm.cfg.xml on the root of the classpath and put in the customized values.
                             -->
                            
                             <string name="resource.varmapping" value="jbpm.varmapping.xml" />
                             <string name="resource.hibernate.cfg.xml" value="hibernate.jbpm.cfg.xml" />
                            
                             <jbpm-context>
                             <service name="persistence">
                             <factory>
                             <bean name="persistence.factory"
                             class="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory">
                            
                             <field name="isTransactionEnabled">
                             <false />
                             </field>
                            
                             </bean>
                             </factory>
                             </service>
                             <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
                             </jbpm-context>
                            
                            </jbpm-configuration>



                            hibernate.ejb.cfg.xml
                            <?xml version='1.0' encoding='utf-8'?>
                            
                            <!DOCTYPE hibernate-configuration PUBLIC
                             "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                             "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
                            
                            
                            <hibernate-configuration>
                             <session-factory>
                             <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
                            
                             <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
                            
                             </session-factory>
                            </hibernate-configuration>


                            hibernate.jbpm.cfg.xml (mappings left out):
                            <?xml version='1.0' encoding='utf-8'?>
                            
                            <!DOCTYPE hibernate-configuration PUBLIC
                             "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                             "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
                            
                            
                            <hibernate-configuration>
                             <session-factory>
                            
                             <!-- hibernate dialect -->
                             <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
                            
                             <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
                            
                             <!-- DataSource properties -->
                             <property name="hibernate.connection.datasource">jdbc/JBPM_DB</property>
                             <!-- DataSource properties (end) -->
                            
                             <!-- JTA transaction properties -->
                             <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
                             <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>
                             <!-- JTA transaction properties (end) -->
                            


                            Any further hints or shared experience on the subject would be highly appreciated.

                            • 11. Re: How can I split storage scheme JBPM and general?
                              copperschnack

                              Hi,

                              we adjusted our jbpm.cfg.xml to use DbPersistenceServiceFactory instead of JtaDbPersistenceServiceFactory. This configuratoin works fine... (read on)

                              <jbpm-context>
                               <service name="persistence">
                               <factory>
                               <bean name="persistence.factory"
                               class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
                              
                               <field name="isTransactionEnabled">
                               <false />
                               </field>
                              
                               </bean>
                               </factory>
                               </service>
                               <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
                               </jbpm-context>


                              ... (continued) UNTIL you want to user the JBPM varmapping to store your Hibernate LongIdInstances. There are some random -or at least confusing- runtime behaviours when using Hibernate as JPA provider as well as JBPM persistence engine. At least there is some confusion regarding responsibility for the persisting of the LongIdInstaces between both Hibernate configurations.

                              We therefore went over to use TopLink as the JPA provider for our EJB3 Entity Beans and keeping Hibernate as JBPM configuration.

                              HTH

                              • 12. Re: How can I split storage scheme JBPM and general?

                                Can you please elaborate about the strange behavior you mentioned? That could help us create a standard solution for splitting the storage

                                • 13. Re: How can I split storage scheme JBPM and general?
                                  slogger

                                  In other words, you still try to split storage between differents DB...
                                  I solved this problem for single DB. I created jbpm tables on behalf of user JBPM and gave grant on this one to general user.
                                  It possible also to create synonym on jbpm tables ;-)

                                  Can you post XA datasource config?