7 Replies Latest reply on Dec 8, 2010 9:43 AM by tmarks

    ESB + JPA/Hibernate?

    tmarks

      A few weeks ago, I successfully created an EJB that could access an Oracle database using hibernate.

      Now, I am looking to add similar code to an ESB (v4.8) application...but have not been able to get it working.

       

      I have searched the documentation and have not found any examples.

      I searched the message board and found no answers.

       

      I tried copying the EJB code to an ESB action class...and tried instantiating an EJB class from my action class.

      Each time, I get a NullPointerException when the EntityManager class is referenced.

       

      Do I have to create an EJB application and call it from my ESB application? (I hope not)

      Can someone point me in the right direction?

        • 1. Re: ESB + JPA/Hibernate?
          tcunning

          What container are you running this in?     What is the code doing?

           

          There are a few quickstarts which might help you - I'd take a look at business_service, ejbprocessor, and helloworld_hibernate_action.

          • 2. Re: ESB + JPA/Hibernate?
            burmanm

            I'm gonna assume that he wants a simple action to use EJB's injection (@PersistenceContext). But that isn't supported inside the .ESB-container at the moment, unless one can deploy .esb package inside an EAR. Which I doubt and I don't know JEE5 enough well to make it work with EJB-injections.

             

            However, those would be nice to simplify database connections.

            • 3. Re: ESB + JPA/Hibernate?
              tmarks

              I have been working on this for several days, I believe I finally figured it out.

               

              I defined 'persistence.xml' within directory <esb>/META-INF.

               

              Within my action class, I did this.

              EntityManagerFactory emf = Persistence.createEntityManagerFactory("hl7-inbound-persist");

              EntityManager em = this.emf.createEntityManager();

              Greeting g = new Greeting();

              g.setMessage("hello");

              em.persist(g);

               

              Record gets persisted to table 'Greeting'

              • 4. Re: ESB + JPA/Hibernate?
                jeffdelong

                It won't work with EJB Injections; you have to treat the ESB service like it was an external client to the EJB. So the action class should look like:

                 

                 

                 

                public class AccountPersistanceAction extends

                AbstractActionPipelineProcessor {

                 

                protected ConfigTree _config;

                 

                private EntityManager em;

                private EntityManagerFactoryImpl  emfImpl;

                private TransactionManager tMgr = null;

                boolean manageTransactionsInAction;

                 

                public AccountPersistanceAction(ConfigTree config) {

                try {

                _config = config;

                // Because ESB services are not handled by EJB deployer, EJB

                // dependency injection isn't going to work.

                // Need to get transaction and entity manager manually

                 

                String entityManagerJNDIName = config.getAttribute("entityManagerJNDIName");

                manageTransactionsInAction = new Boolean( config.getAttribute("manageTransactionsInAction") );

                 

                InitialContext jndiContext = new InitialContext();

                SessionFactory sFactory = (SessionFactory)jndiContext.lookup(entityManagerJNDIName);

                emfImpl = new EntityManagerFactoryImpl(sFactory, PersistenceUnitTransactionType.JTA, true, null);

                tMgr = (TransactionManager)jndiContext.lookup("java:/TransactionManager");

                 

                 

                 

                public Message process(Message message) throws ActionProcessingException {

                // make a copy of the message

                newMessage = message.copy();

                 

                Map accountPayload = (Map) newMessage.getBody().get(“accountPayload”);

                Task task = (Task) accountPayload.get("task");

                String taskName = (String) task.getTaskName();

                 

                try {

                if (manageTransactionsInAction) {

                beginTransaction();

                }

                 

                // create an entityManager and join the transaction

                em = emfImpl.createEntityManager();

                em.joinTransaction();

                 

                 

                if (taskName.startsWith("create")) {

                Account account = (Account) accountPayload.get("account")

                em.persist(account);

                 

                }

                 

                ....

                 

                 

                 

                A transaction is required. Your action class can manage it, or you can have the container manage it by using a JCA JMS Provider / Listener.

                • 5. Re: ESB + JPA/Hibernate?
                  burmanm

                  Yep, exactly, not too pretty. That's why injections are so nice. There was a summer code project proposal for CDI, but I guess it never happened?

                  • 6. Re: ESB + JPA/Hibernate?
                    jeffdelong

                    An alternate approach is to create a SLSB that manages the persistent entity and expose it as a Web service using JSR-181 annotations, then use a SOAPProxy action in the ESB service to invoke the Web service.

                    • 7. Re: ESB + JPA/Hibernate?
                      tmarks

                      Jeff - Thanks for the detailed response.

                       

                      I am currently not creating the SessionFactory or TransactionManager as you showed in your sample code.

                      Is it required based upon my persistence.xml? (shown below).

                      My JMS queue is configured with 'transacted=true'.

                      I am looking for any insert/update/deletion to get rolled back when an Exception occurs within the action chain.

                      Any suggestions appreciated.

                       

                      <?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"
                      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="hl7-inbound-persist">
                            <provider>org.hibernate.ejb.HibernatePersistence</provider>
                      <!--
                            <jta-data-source>java:DefaultDS</jta-data-source>
                      -->
                            <properties>
                               <property name="hibernate.hbm2ddl.auto" value="create"/>
                               <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
                               <property name="hibernate.show_sql" value="true"/>
                               <property name="hibernate.format_sql" value="true"/>
                               <property name="hibernate.connection.datasource" value="java:DefaultDS"/>
                               <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
                               <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
                            </properties>
                         </persistence-unit>
                      </persistence>