Hi,
There is a trouble related to Hibernate in the following situation:
- When it runs on OC4J (10g 10.1.2.0.0);
- It uses EJB + CMT;
My hibernate.cfg.xml:
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:hibernate/SessionFactory">
<property name="connection.datasource">java:comp/env/jdbc/BancoDS</property>
<property name="show_sql">false</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="use_outer_join">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.connection.release_mode">auto</property>
<property name="hibernate.transaction.auto_close_session">true</property>
<property name="hibernate.transaction.flush_before_completion">true</property>
<property name="transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.OrionTransactionManagerLookup</property>
<mapping resource="Account.hbm.xml"/>
</session-factory>
</hibernate-configuration>
My code:
Code:
(...)
public void save(Account acc)
{
Session s = sessionFactory.getCurrentSession();
s.save(acc);
}
(...)
Error message:
Code:
org.hibernate.HibernateException: Could not locate TransactionManager
at org.hibernate.transaction.JNDITransactionManagerLookup.getTransactionManager(JNDITransactionManagerLookup.jav
a:26)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:270)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
(...)
Caused by: javax.naming.NameNotFoundException: Only session and message-driven beans with bean-managed transaction are a
llowed to use UserTransaction
When this error happens? On SessionFactory initilization:
Code:
(...)
try
{
sessionFactory = new Configuration().configure()
.buildSessionFactory();
}
catch (Throwable ex)
{
throw new ExceptionInInitializerError(ex);
}
(...)
Reading specification on item J2EE.5.6
UserTransaction References
Certain J2EE application component types are allowed to use the JTA UserTransaction interface to start, commit, and abort transactions. Such application components can find an appropriate object implementing the UserTransaction interface by looking up the JNDI name java:comp/ UserTransaction. The container is only required to provide the java:comp/UserTransaction name for those components that can validly make use of it. Any such reference to a UserTransaction object is only valid within the component instance that performed the lookup. See the individual component definitions for further information.
The following example illustrates how an application component acquires and uses a UserTransaction object.
We can suggest that OC4J is throwing an exception when SessionFactory tries to lookup the UserTransaction, because EJB is marked as CMT (see red letters).
If I use org.hibernate.transaction.JDBCTransactionFactory as my transaction.factory_class it works well and it's possible to call multiple CMT EJB under same transaction, but I have to flush() everytime I change an object, making performance worse than flushing on commit.
Using JDBCTransactionFactory, I'll loose every resource related to JTA:
- hibernate.transaction.auto_close_session
- hibernate.transaction.flush_before_completion
The thing is that everything is running well, but it should be better if I could integrate Hibernate to OC4J (and spec) TransactionManager. Isn't it a problem if every Application Server decides to work as OC4J (and possibly WebSphere) works? Throwing an exception when some CMT EJB tries to lookup an UserTransaction? Or worse than this, Hibernate is using something optional?