we use hibernate, oracle and pessimstic locking, to avoid concurrent modification through different threads.
This worked fine for a while. But now we sometimes get deadlocks. We analyzied and found the cause: we produced locks with different deepnesses for objects of type joined subclass.
An example for our kind of mapping:
session.get(Class clazz, Serializable id, LockMode lockMode);
SELECT traceobjec0_.objectId ... FROM TraceObjects traceobjec0_ LEFT OUTER JOIN VehicleObjects traceobjec0_3_ ON traceobjec0_.objectId=traceobjec0_3_.id WHERE traceobjec0_.objectId=? FOR UPDATE;
This locks the relevant data in table TraceObjects and joined table VehicleObjects.
session.get(Class clazz, Serializable id);
session.lock(Object object, LockMode lockMode);
select traceobjec0_.objectId ... from TraceObjects traceobjec0_ left outer join VehicleObjects traceobjec0_3_ on traceobjec0_.objectId=traceobjec0_3_.id where traceobjec0_.objectId=?;
select objectId from TraceObjects where objectId =? for update;
This only locks the relevant data in table TraceObjects.
We think this is a bug, because all techniques to lock should create the same lock type (only locking the parent table).
I'm using the related NHibernate project (a near direct port of Hibernate to .NET, though a little behind) and have encountered a locking problem that I think may be related to this one.
In my case, I'm using SQL Server which uses "SELECT ... FROM <table> WITH (updlock) WHERE ..." syntax instead of Oracle's "SELECT ... FROM <table> WHERE ... FOR UPDATE" syntax. When I do session.get(Class clazz, Serializable id, LockMode.Upgrade) for a joined subclass, it generates the following pattern:
SELECT ... FROM TraceObjects WITH (updlock,rowlock) LEFT OUTER JOIN VehicleObjects ON ...
This ends up with a "U" Upgrade lock on TraceObjects and a "S" Shared lock on VehicleObjects, effectively locking only TraceObjects. For me, this leads to a deadlock when NHibernate late attempts to UPDATE VehicleObjects which acquires an "X" Exclusive lock.
No I saw it stated in the NHibernate Users Group ("Dirty optimistic locking" https://groups.google.com/forum/?fromgroups=#!topic/nhusers/QbhORn71YKc) that subclass table locking is purposefully NOT done to avoid certain deadlock situations. But it appears that the Oracle dialect (or even Oracle's syntax?) is caused both tables in the join to be locked (a behavior I believe would solve my deadlock if I could get MS SQL Server to do that!), which violates the statement I found – not that the statement is sacred and true.
But what this means to me is that the MsSqlXxxDialects and OracleXxxDialects have very real differences in how locks are applied to the tables in a joined-subclass, and specifically for Oracle the locking differs on whether the lock is acquired during "get" or a later "lock".
It would seem the dialects should be consistent within themselves ("get" vs. "lock") and also consistent with each other (MsSqlXxxDialect vs. OracleXxxDialect).
In an effort to clean up, in bulk, tickets that are most likely out of date, we're transitioning all ORM 3 tickets to an "Awaiting Test Case" state. Please see http://in.relation.to/Bloggers/HibernateORMJIRAPoliciesAndCleanUpTactics for more information.
If this is still a legitimate bug in ORM 4, please provide either a test case that reproduces it or enough detail (entities, mappings, snippets, etc.) to show that it still fails on 4. If nothing is received within 3 months or so, we'll be automatically closing them.
Bulk rejecting stale issues. If this is still a legitimate issue on ORM 4, feel free to comment and attach a test case. I'll address responses case-by-case. Thanks!