Hi All
We're currently in the process of investigating Hibernate in order to get rid of Entity Beans. One major concern is, whether Hibernate does proper transaction handling. Therefore I did the following test:
My business classes consist of a parent class Wertpapier and a child class Kurs. A Wertpapier can contain many Kurses.
I have a method creating a Wertpapier and two Kurses, and then Hibernate persists them into our Oracle DB.
I have a second method which does a find for Wertpapiers and deletes them. Since I specified the one-to-many relation as cascade-all, the Kurses are deleted as well.
Both methods do open and close again their own session and transaction.
Create Method:
Code:
Session aSession = null;
Transaction t = null;
try {
aSession = HibernateUtil.getInstance().getMySessionFactory().openSession();
t = aSession.beginTransaction();
Wertpapier w = new Wertpapier();
w.setNlsKey(NLS_1);
w.setValor(7);
Kurs k1 = new Kurs();
k1.setBetrag(123.5f);
k1.setWaehrung("CHF");
k1.setZeitstempel(GregorianCalendar.getInstance().getTime());
k1.setWertpapier(w);
w.addKurs(k1);
Kurs k2 = new Kurs();
k2.setBetrag(321);
k2.setWaehrung("USD");
k2.setZeitstempel(GregorianCalendar.getInstance().getTime());
k2.setWertpapier(w);
w.addKurs(k2);
aSession.save(w);
t.commit();
t = aSession.beginTransaction();
List wps = aSession.find("from Wertpapier as wp where wp.nlsKey = ?", NLS_1, Hibernate.STRING);
assertTrue(1 <= wps.size());
assertEquals(NLS_1, ((Wertpapier) wps.get(0)).getNlsKey());
t.commit();
} catch (HibernateException e) {
if (t != null) {
t.rollback();
}
} finally {
aSession.close();
}
Cleanup method:
Code:
Session aSession = null;
Transaction t = null;
try {
aSession = HibernateUtil.getInstance().getMySessionFactory().openSession();
t = aSession.beginTransaction();
List wps = aSession.find(
"from Wertpapier as wp where wp.nlsKey in (?, ?)",
new Object[]{NLS_1, NSL_2},
new Type[]{Hibernate.STRING, Hibernate.STRING}
);
for (Iterator iter = wps.iterator(); iter.hasNext();) {
aSession.delete(iter.next());
}
t.commit();
}
catch (HibernateException e) {
if (t!=null) {
t.rollback();
}
}
finally {
aSession.close();
}
Now I started 10 threads. Each thread calls the two methods 10 times.
Most of the time this test works fine, but every now and then I get the following exceptions:
Code:
[java] ERROR 28.01 15:24:07,894 til.JDBCExceptionReporter [java.sql.SQLException: ORA-00060: Deadlock beim Warten auf Ressource festgestellt
[java] ] '1'
[java] WARN 28.01 15:24:07,894 til.JDBCExceptionReporter [SQL Error: 0, SQLState: null] '1'
[java] ERROR 28.01 15:24:07,894 til.JDBCExceptionReporter [java.sql.SQLException: ORA-00060: Deadlock beim Warten auf Ressource festgestellt
[java] ] '1'
[java] ERROR 28.01 15:24:07,894 til.JDBCExceptionReporter [Could not execute JDBC batch update] '1'
[java] java.sql.SQLException: java.sql.SQLException: ORA-00060: Deadlock beim Warten auf Ressource festgestellt
[java] at weblogic.jdbc.rmi.SerialStatement.executeBatch(SerialStatement.java:450)
[java] at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
[java] at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:118)
[java] at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2311)
[java] at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2266)
[java] at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2187)
[java] at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
[java] at ch.postfinance.bom.dummy.WertpapierServerTest.cleanup(WertpapierServerTest.java:75)
[java] at ch.postfinance.bom.dummy.WertpapierServerTest.setUp(WertpapierServerTest.java:39)
[java] at org.apache.cactus.AbstractTestCase.runBareServerTest(AbstractTestCase.java:233)
[java] at org.apache.cactus.server.AbstractWebTestCaller.doTest(AbstractWebTestCaller.java:149)
.....
[java] ERROR 28.01 15:24:08,003 ibernate.impl.SessionImpl [Could not synchronize database state with session] '1'
[java] net.sf.hibernate.JDBCException: Could not execute JDBC batch update
[java] at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:125)
[java] at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2311)
[java] at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2266)
[java] at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2187)
[java] at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
[java] at ch.postfinance.bom.dummy.WertpapierServerTest.cleanup(WertpapierServerTest.java:75)
[java] at ch.postfinance.bom.dummy.WertpapierServerTest.setUp(WertpapierServerTest.java:39)
[java] at org.apache.cactus.AbstractTestCase.runBareServerTest(AbstractTestCase.java:233)
.....
[java] Caused by:
[java] java.sql.SQLException: java.sql.SQLException: ORA-00060: Deadlock beim Warten auf Ressource festgestellt
[java] at weblogic.jdbc.rmi.SerialStatement.executeBatch(SerialStatement.java:450)
[java] at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
[java] at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:118)
[java] ... 33 more
I'm not sure what this means. Is this Oracles way of telling me, that there's optimistic locking conflict. That would be fine for me. Or is there something I'm doing wrong?
Any help is appreciated
Ernst