setup: spring 2.5.6 + Hibernate 3.1 (annotation driven) + Oracle 11g
problem: I am seeing the same object being deleted twice from within one of my DAO methods. This causes the connection deadlock due to next row locking (until oracle figures out the current connection already owns the lock) , since the first deletion took out a lock on the deleted row.
SQL: delete from DerivationPath where id = 3 and optlock = 1
...
SQL: delete from DerivationPath where id = 3 and optlock = 1I believe that a cascade of delete_orphan is the cause. I'm trying to understand exactly how this is happening. Is this expected behavior for hibernate or is my
annotations somehow wrong?
Here is a simplified domain model -- a person has a set of documents (a set of documents which can be derived from other documents). Note the DerivationPath is always a directed acyclic graph. The deadlock does not always occur, it seems to depends on the object graph; in particular, this case causes double delete:
Code:
[Document 1]-- \
+ [DerivationPath]--- [Document 3]
[Document 2] --/
Test case:
Code:
Person p = getHibernateTemplate.loadById(id, Person.class);
getHibernateTemplate.delete(P);
...
Domain model:
Code:
class Person {
@OneToMany(mappedBy = "personBackRef", cascade = { CascadeType.ALL }) // JPA annotation
@Cascade( { SAVE_UPDATE }) // Hibernate annotation
public List<Document > getDocuments() {
}
class Document {
@OneToOne // JPA
@Cascade( { SAVE_UPDATE, DELETE_ORPHAN }) // hibernate
public DerivationPath getDerivationPath();
}
class DerivationPath {
@OneToMany // JPA
List<Document> getSource();
}