Thank you Sukirtha for your reply.
I've done the test you proposed and some more (They're not JUnit tests, but i will use the PASS and FAIL notation). These are the results:
TEST using factory.getCurrentSession() instead of factory.openSession(): FAILResult: factory.getCurrentSession() returns null. The next tests use always factory.openSession()
TEST Creating One object: PASSCode:
protected int saveFile() throws Exception {
int resp = 0;
HibernateFunctions functions = new HibernateFunctions();
Transaction transaction = null;
Session session = null;
try {
session = functions.getSession();
transaction = session.beginTransaction();
MyObj obj = new MyObj();
obj.setMyField("my_value");
session.save(obj);
transaction.commit();
}
catch (HibernateException e) {
transaction.rollback();
throw e;
}
finally {
functions.closeSession();
}
return resp;
}
TEST Creating two objects: FAILCode:
protected int saveFile() throws Exception {
int resp = 0;
HibernateFunctions functions = new HibernateFunctions();
Transaction transaction = null;
Session session = null;
try {
session = functions.getSession();
transaction = session.beginTransaction();
MyObj obj1 = new MyObj();
obj1.setMyField("my_value");
MyObj obj2 = new MyObj();
obj2.setMyField("my_value"); // the UK is violated since both
//objects have the same value for myField
session.save(obj1);
session.save(obj2);
transaction.commit();
}
catch (HibernateException e) {
transaction.rollback();
throw e;
}
finally {
functions.closeSession();
}
return resp;
}
It obviously throws an ERROR [JDBCExceptionReporter] ORA-00001: unique constraint (CONSOLIDATION_UK) violated. The problem is that the tables remain locked in the database after this.
So, following Sukirtha suggestion, I've not used the HibernateFunctions class. Rather, i've obtained the factory and the session directly.
TEST Creating one object, obtaining session directly: PASSCode:
protected int saveFile() throws Exception {
int resp = 0;
InitialContext ctx = new InitialContext();
SessionFactory factory = (SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");
Session session = null;
Transaction transaction = null;
try {
session = factory.openSession();
transaction = session.beginTransaction();
MyObj obj1 = new MyObj();
obj1.setMyField("my_value");
session.save(obj1);
transaction.commit();
}
catch (HibernateException e) {
transaction.rollback();
throw e;
}
finally {
functions.closeSession();
session.close();
}
return resp;
}
Result: Object is correctly inserted in the database and no table becomes locked. :)
TEST Creating two objects, obtaining session directly: FAILCode:
protected int saveFile() throws Exception {
int resp = 0;
InitialContext ctx = new InitialContext();
SessionFactory factory = (SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");
Session session = null;
Transaction transaction = null;
try {
session = factory.openSession();
transaction = session.beginTransaction();
MyObj obj1 = new MyObj();
obj1.setMyField("my_value");
MyObj obj2 = new MyObj();
obj2.setMyField("my_value"); // the UK is violated since both
//objects have the same value for myField
session.save(obj1);
session.save(obj2);
transaction.commit();
}
catch (HibernateException e) {
transaction.rollback();
throw e;
}
finally {
functions.closeSession();
session.close();
}
return resp;
}
Result: Exception is thrown, and correctly catched by the catch block. But even after the transaction.rollback() and session.close(), tables remain locked.
TEST Creating one object, obtaining session directly, executing code twice: PASSThe first time the code is executed, the row is correctly inserted in the database.
The second time the code is executed, an exception is thrown, the transaction is correctly rolled back and no tables remain locked.
Observations The lock (deadlock?) is ocurring when
two records violate the Unique Key in the same transaction. When the UK is violated in another transaction, it works as expected.
So, am I doing something wrong here? What else should I try? What can I do to get rid of those eternal table locks?
Thank you. Your help is very appreciated.
Braiam.