Configuring Hibernate to be using in an Enterprise Application based
on J2EE Technology, running on JBoss Application Server 5.0.0 Beta3,
to use CMT (EJB Container Managed Transaction).

    Third party Advertisement
Objectives: To demonstrate capability towards configuring/ using CMT (Container Managed Transaction) from Stateless Session Bean to Business Object and to SessionFactory (Hibernate Session Factory) to Database. Solution: A demo program, having WEB Layer, EJB Style, Data Access Object and Database is to be designed and deployed to JBoss Application Server. Software Environment: 1. JDK 1.5.0_04 2. JBoss 5.0.0 Beta3 3. Hibernate 3.2 4. Apache ANT Intention of this demonstration is to show a working model of using Transaction in EJB Container from Session Bean to Database. Web tier is made very simple, by having a JSP, that uses a helper JavaBean to call a method on a Remote Session Bean. Getting Home interface is done by using Service Locator design pattern. Session Bean is defined as Stateless and could be acting like SessionFacade and this session bean has CMT (Container Managed Transaction) initiated by the Application Server (JBoss Application Server). Business service is defined in POJO and business method gets invoked by Session Bean, with either Container Managed Transaction scope or Bean managed Transaction scope, as defined in ejb-jar.xml file. Business Object calls/ invokes DAO implementation to store/retrieve value objects. DAO implementation has wrapped Hibernate related api, such as SessionFactory and Session, and uses various methods like save, saveOrUpdate, update, get, load of Hibernate Session instance to perform required database operation.
    Third party Advertisement
Now in this entire process, Transaction is getting initiated at Session bean level and is propagated to business object, then to DAO and to Hibernate Session and finally database related operations. So the entire business method execution happens within a distributed application server Transaction. In case of any type of database exception/ failure, this entire operation gets rollback by Transaction, thus maintaining database consistency. This demo has hibernate.cfg.xml file, as explained below: <session-factory name="<JNDI-Name>"> <!-- properties --> <property name="connection.datasource">java:OracleDS</property> <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property> <property name="show_sql">true</property> <!-- property for JTA (Bean Managed Transaction) compatible Hibernate Transaction Factory --> <!-- <property name="transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> --> <!-- property for CMT (Container Managed Transaction) compatible Hibernate Transaction Factory --> <property name="transaction.factory_class"> org.hibernate.transaction.CMTTransactionFactory </property> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.JBossTransactionManagerLookup </property> <property name="jta.UserTransaction">UserTransaction</property> <property name="hibernate.current_session_context_class"> org.hibernate.context.JTASessionContext </property> <mapping resource="demo/admin/Application.hbm.xml"/> </session-factory> This hibernate.cfg.xml file can define SessionFactory with a JNDI name , which can be looked up by any utility for accessing single instance of Hibernate SessionFactory. The need for binding SessionFactory to JNDI namespace is to avoid re-creating SessionFactory for every operation, as it is advisable to use a single SessionFactory for the entire application, but limiting Session instance retrieved from SessionFactory, to a single business operation. As SessionFactory creation is resource intensive operation and it is always stateless. The section commented in the above hibernate.cfg.xml file, is for JTA (Java Transaction API). If enabled Programmatic JTA transaction can be initiated by Session Bean by looking up UserTransaction. This transaction will be propagated to Hibernate Session and on completion of Database operation, Session will be flushed and transaction will be committed (in case of any database exception, transaction will be roll backed). The section in BOLD, is the CMT (Container Managed Transaction) factory that is for using CMT transaction defined in the ejb-jar.xml session bean descriptor file, <transaction-type>Container<transaction-type> and for JTA, or programatic UserTransaction, this will be changed to <transaction-type>Bean<transaction-type> The datasource defined in hibernate.cfg.xml file has to be defined in Application Server, in JBoss Application Server, I have created a file as Oracle-ds.xml with the following contents: <datasources> <local-tx-datasource> <jndi-name>OracleDS</jndi-name> <connection-url> jdbc:oracle:thin:@<Oracle database host name/ip>:1521:<NET Configuration service name> </connection-url> <driver-class>oracle.jdbc.driver.OracleDriver</driver-class> <user-name>db user name</user-name> <password>encrypted password</password> </local-tx-datasource> </datasources> This datasource file has to be placed in %JBoss_Home%/server/default/deploy folder, if the server profile is 'default'. For testing JTA programmatic UserTransaction to be looked /used in Session Bean and propagating it to Hibernate Session for database operations, there will be changes as follows: 1. ejb-jar.xml file: <transaction-type>Bean</transaction-type> 2. hibernate.cfg.xml file: Un-comment JTATransactionFactory and comment CMTTransactionFactory section/ tags. 3. Session bean code will be using JNDI to look up UserTransaction from InitialContext, and beginning this UserTransaction and Committing it in finally block or rolling back entire Transaction, in case of any database related Exception. Add your suggestions here