Hello OpenEJBers, 

  
I am new to OpenEJB, as well as large parts of the JavaEE stack and core
tools (EJB, JTA, JPA, Hibernate, ...).  We are in the process of migrating a
legacy EJB 2 application from the JBoss environment to Tomcat 6 under Java
1.5, using embedded OpenEJB 3.1.2 to support the existing EJBs, and
generally to fill the gaps created by leaving the full application server
environment of JBoss behind.  The application currently uses Hibernate 2.1
with MySQL-based data sources to provide persistence.  It has been
restructured from its original EAR packaging into various webapps/WARs, with
one primary webapp taking care of all EJBs, database access, and transaction
processing.  My preference, at least initially, is to minimize code changes
and solve as many problems as possible through OpenEJB/Hibernate/Tomcat
configuration. 

This webapp with its EJBs and data sources is deployed in a development
environment with Tomcat-OpenEJB, and is able to update the MySQL database
successfully.  Until recently the data source was defined as a Tomcat global
JNDI resource in server.xml, not managed by OpenEJB.  However, JTA
transactions are not working properly, with no ability to rollback failed
updates.  I have been working on this problem for a few days, and have
reached the point where some help would be very welcome! 
  
At first I installed the JOTM package in the Tomcat environment outside of
OpenEJB to provide transaction support, modifying the legacy
hibernate.cfg.xml to reference the necessary JOTM transaction factory and
transaction manager lookup classes with no use of OpenEJB.  (Yes, I know
that OpenEJB supports JTA with no need for another package, but this
approach was set up mostly before OpenEJB was introduced.)  However, the
JOTM classes did not appear to be executed at all from either Hibernate or
the OpenEJB, and I abandoned this approach as probably sub-optimal in any
case.  My current direction is to upgrade the environment from Hibernate 2.1
to 3.4.0 -- as it appears that OpenEJB does not contain support for pre-3.x
Hibernate versions -- and migrate the data source and transaction management
resources from Tomcat into OpenEJB. 
  
  
I have moved the MySQL data source definition out of server.xml and into
openejb.xml with configuration like the following: 
  
  <Resource id="jdbc/LsBpmDS" type="DataSource"> 
     JdbcDriver com.mysql.jdbc.Driver 
     JdbcUrl jdbc:mysql://localhost:3306/mydb?autoReconnect=true 
     UserName ... 
     Password ... 
     JtaManaged true 
  </Resource> 

  
  
The ejb-jar.xml inside the WAR file META-INF/ has many entries like the
following for the EJBs and their data source references: 

    <session id="AuthenticationService"> 
      <ejb-name>lsbpm/AuthenticationService</ejb-name> 
     
<local-home>com.myorg.myapp.services.authentication.AuthenticationServiceHome</local-home>
 
     
<local>com.myorg.myapp.services.authentication.AuthenticationService</local> 
     
<ejb-class>com.myorg.myapp.services.authentication.AuthenticationServiceBean</ejb-class>
 
      <session-type>Stateless</session-type> 
      <transaction-type>Container</transaction-type> 
  
      <resource-ref id="AuthenticationServiceDS"> 
       <description></description> 
       <res-ref-name>jdbc/LsBpmDS</res-ref-name> 
       <res-type>javax.sql.DataSource</res-type> 
       <res-auth>Container</res-auth> 
       <res-sharing-scope>Shareable</res-sharing-scope> 
      </resource-ref> 

      ... 
  
  
With OpenEJB debug logging enabled, the Tomcat logs show that OpenEJB
successfully maps the EJB resources to the above jdbc/LsBpmDS data source on
startup. 
  
  
The hibernate.cfg.xml file is currently stored in <Tomcat home>/lib/ with
the following content: 
  
<?xml version='1.0' encoding='utf-8'?> 
<hibernate-configuration> 
     <session-factory> 
        <property
name="connection.datasource">java:comp/env/jdbc/LsBpmDS</property> 
        <property
name="dialect">org.hibernate.dialect.MySQLDialect</property> 
        <property name="show_sql">false</property> 
        <property name="use_outer_join">true</property> 
        <property
name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
 
         <property
name="hibernate.transaction.manager_lookup_class">org.apache.openejb.hibernate.TransactionManagerLookup</property>
 
         <property
name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
 

        <!-- mapping files --> 
        <mapping resource="MySQL/AuthToken.hbm.xml"/> 
        <mapping resource="MySQL/HibACE.hbm.xml"/> 
        ... 
    </session-factory> 
</hibernate-configuration> 

  
The mapping files MySQL/*.hbm.xml referenced in hibernate.cfg.xml are
currently packaged in a JAR that is deployed in the webapp's WEB-INF/lib/
directory, although I have tried other locations (more about that below). 
The following Hibernate 3 JARs and dependencies have also been deployed. 
  
antlr-2.7.6.jar 
dom4j-1.3.jar 
ehcache-1.3.0.jar 
ejb3-persistence-1.0.2.GA.jar 
hibernate-annotations-3.4.0.GA.jar 
hibernate-commons-annotations-3.1.0.GA.jar 
hibernate-core-3.3.0.SP1.jar 
hibernate-entitymanager-3.4.0.GA.jar 
javassist-3.4.GA.jar 
slf4j-api-1.4.2.jar 
slf4j-jdk14-1.4.2.jar 
  
  
There are no errors at Tomcat startup, but the following error is raised in
the catalina log when attempting to process any update in the application. 
  
SEVERE: Could not instantiate TransactionManagerLookup 
java.lang.ClassCastException:
org.apache.openejb.hibernate.TransactionManagerLookup 
 at
org.hibernate.transaction.TransactionManagerLookupFactory.getTransactionManagerLookup(TransactionManagerLookupFactory.java:86)
 
 at
org.hibernate.transaction.JTATransactionFactory.resolveUserTransactionName(JTATransactionFactory.java:136)
 
 at
org.hibernate.transaction.JTATransactionFactory.configure(JTATransactionFactory.java:94)
 
 at
org.hibernate.transaction.TransactionFactoryFactory.buildTransactionFactory(TransactionFactoryFactory.java:79)
 
 at
org.hibernate.cfg.SettingsFactory.createTransactionFactory(SettingsFactory.java:452)
 
 at
org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:165) 
 at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2101) 
 at
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1325) 
 at ... 
  
  
Casting exceptions are often indicators of version mismatches within the
environment, but here I think that the OpenEJB and Hibernate versions with
their dependencies are all compatible.  I have modified the application
code, primarily package names, in order to upgrade to Hibernate 3 in a
minimal way (that is, without reworking the code to remove deprecated
methods), but the above error looks like it is in the stack rather than the
app.  I have not found much on the web to help here.  Any suggestions? 
  
  
Another related point is the location of the Hibernate-related JARs and
configuration-mapping files mentioned above.  I expect that, given that
OpenEJB is now managing the transactions and calls to Hibernate as well as
the EJBs, the best location to save these JAR files and hibernate.cfg.xml is
probably <Tomcat home>/lib/, rather than in either the application or
openejb webapp.  However, when testing this way the processing does not even
reach the above error, but instead raises the following one. 
  
ERROR - The bean instance com.myorg.myapp.myb...@edeea8 threw a system
exception:javax.ejb.EJBException: org.hibernate.HibernateException: Could
not parse configuration: /hibernate.cfg.xml 
javax.ejb.EJBException: org.hibernate.HibernateException: Could not parse
configuration: /hibernate.cfg.xml 
 at com.myorg.myapp.MyBean.ejbCreate(MyBean.java:69) 
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
 at ... 
  
  
I know that the syntax of hibernate.cfg.xml itself is correct and can be
found by Hibernate, given that in the first test it is being parsed
correctly by Hibernate and also based on independent XML parser checks.  All
the Hibernate config files have been updated to reference the Hibernate 3.0
rather than 2.0 DTDs.  I am fairly sure that the error is being raised
because the mapping files MySQL/*.hbm.xml files referenced inside
hibernate.cfg.xml are not being found at runtime.  However, I can't find the
proper place to put them!  They are currently packaged in a JAR file, and I
have tried placing this JAR file in <Tomcat home>/lib/, <openejb
webapp>/lib/, and <openejb webapp>/WEB-INF/lib/.  I have also tried
unpacking the MySQL/*.hbm.xml tree into the same directories, with no luck. 
I was able to pass the parsing error by deploying all the above
Hibernate-related JARs both into the application webapp WEB-INF/lib/
directory and in <Tomcat home>/lib/, along with the JAR that contains the
MySQL/*.hbm.xml files; after which I ran into the first Java error mentioned
above.  I am sure that deploying these JARs in two places at once in the
Tomcat environment is a bad idea, but where should they go? 
  
  
To close this message: I have seen many (rather confusing) posts and partial
examples regarding the use of the config files persistence.xml,
services-jar.xml, and/or openejb-jar.xml files to define data source
resources, Hibernate properties, and transaction managers more explicitly
inside OpenEJB.  However, it seems to me based on other doc I have read that
using openejb.xml, ejb-jar.xml, and the native Hibernate files should be
enough for a seemingly straightforward case like this one.  If this is
wrong, please steer me in the right direction. 
  
  
Thx in advance, 
Fred 

-- 
View this message in context: 
http://n4.nabble.com/Transaction-Problems-with-OpenEJB-Hibernate-on-Tomcat-tp1011003p1011003.html
Sent from the OpenEJB User mailing list archive at Nabble.com.

Reply via email to