[jboss-user] [EJB 3.0] New message: "Legacy app as a service POJO, using EJB3, Hibernate and BMT..."

Stephan Steiner do-not-reply at jboss.com
Tue Mar 16 03:47:09 EDT 2010


User development,

A new message was posted in the thread "Legacy app as a service POJO, using EJB3, Hibernate and BMT...":

http://community.jboss.org/message/532159#532159

Author  : Stephan Steiner
Profile : http://community.jboss.org/people/sepan77

Message:
--------------------------------------------------------------
Hello,
I need to wrap a legacy application to be run within a JBoss Container (4.2.2). The application follows the "chain of responsibility" pattern (XML messages received from a remote webservice are processed and the extracted data is stored in a database). This workflow needs to be customizable and the configuration is read from the database on startup of the application. Hibernate is used to access the database. Each processing step must be performed as a single transaction, so that if one processing step fails, the previous steps are not compromised.
For that reason, I need to use bean managed transactions. Since the application reads its workflow configuration from the database at startup, I need a single instance. Because of that and because it came convenient to me, I exposed the main methods of the application as a Service Pojo MBean which holds the single instance of the legacy application.
So far, so good. Everything seems to work fine, but sometimes the database transactions are not committed. This is actually very strange and happens most of the time when the application server is under load, but this behaviour is rather irrational to me.
Here are a few extracts of the code:
 
Service Pojo:
@Service(objectName = MyAppService.SERVICE_NAME, xmbean = "resource:META-INF/myappservice-xmbean.xml")
@Local(MyAppServiceLocal.class)
@Remote(MyAppServiceRemote.class)
@TransactionManagement(TransactionManagementType.BEAN)
public class MyAppService implements EMCSServiceLocal, EMCSServiceRemote {
    public static final String SERVICE_NAME = "at.xyz.myapp:service=MyAppService";
    
    private MyApp appInstance;   // <-- application instance
   @PersistenceUnit SessionFactory factory;  // <--- injected session factory, since app uses hibernate
 
   // lazy initialization of application
   private MyApp getAppInstance() {
      if (appInstance == null) {
         appInstance = new MyApp();
         Session session = factory.openSession();
         try {
           appInstance.configureFromDb(session);
         } catch (Exception ex) {
           ...
         } finally {
            try { session.close(); } catch (Exception ex) {}
         }
      }
      return appInstance;
   }
 
 
   // business method of application exposed to MBean
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void fetchMessages() {
        Session session = factory.openSession();
        try {
            getAppInstance().fetchMessages(session);
        } catch (Exception ex) {
            ...
        } finally {
            try { session.close(); } catch (Exception ex) { ... }
        }
    }
 
   // another business method of application exposed to MBean
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void processMessage(long id) {
        Session session = factory.openSession();
        try {
            getAppInstance().processMessage(session, id);
        } catch (Exception ex) {
            ...
        } finally {
            try { session.close(); } catch (Exception ex) { ... }
        }
    }
}
 
 

 
An the application itself (just showing the example for fetchMessages):
 
public void fetchMessage(Session session) {
  // this is just for illustration. the single processing steps are contained within single classes using a command pattern.
 
  // processing step 1
  Transaction tx = session.beginTransaction();
  try {
    // do some work: load/save entities from database, perform queries
    tx.commit();
  } catch (HibernateException ex) {
    try {
      tx.rollback();
    } catch (HibernateException ex2) {}
  }
 
  // processing step 2
  Transaction tx = session.beginTransaction();
  try {
    // do some work: load/save entities from database, perform queries
    tx.commit();
  } catch (HibernateException ex) {
    try {
      tx.rollback();
    } catch (HibernateException ex2) {}
  }
}

 
The persistence unit is configured using JTA, so it should be ok:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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_1_0.xsd">
    <persistence-unit name="emcs" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/MYAPPDS</jta-data-source>

        <!-- legacy application containing business logic and entities -->
        <jar-file> ../lib/myapp.jar </jar-file>

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
            <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />
            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
            <property name="hibernate.current_session_context_class" value="jta"/>
        </properties>
    </persistence-unit>
</persistence>


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

To reply to this message visit the message page: http://community.jboss.org/message/532159#532159




More information about the jboss-user mailing list