Situation: I have an entity class Employee which is a subclass of the abstract entity class Person. The inheritance strategy is of type joined. In our project we use the convention that the primary key column name of each database table is %ENTITY_NAME%_ID.
To do some calculations on employee related details, I need to put a read/write lock on the employee entity, te ensure that the calculation will not be executed based on stale data.
So, when I try to put a lock on the employee entity instance by calling entityManager.lock(employee, LockModeType.OPTIMISTIC_FORCE_INCREMENT), I get a JdbcSQLException when the entityManager is flushing it's state to the database:
As you can see in the exception details, the wrong id column name is used in the update predicate. Instead, it should generate the following query:
I've managed to reproduce the bug in a hibernate test case. The test code can be found here.
I think I've found the cause of this bug in the hibernate sources. It seems like the generateVersionIncrementUpdateString() method in org.hibernate.persister.entity.AbstractEntityPersister generates invalid update statements when a version increment is applied to an @Inheritance annotated entity. This is the case when different primary key column names are used in the table structure of the inheritance tree. In that case, an instance of JoinedSubclassEntityPersister is used to generate this update statement. The table name of the table which holds the version column is retrieved by invoking getTableName(0), which returns the first table name of the inheritance natural order list. On the other hand, the identifier column names are retrieved by invoking getIdentifierColumnNames(), which returns the first key columns entry of the array holding the inheritance reversed order list.
My assumption is that the identifier column names (name*s*, because the identifier of the table can be composite key) should be retrieved by invoking getKeyColumns(0), which returns the first entry of the naturalOrderTableKeyColumns array.
I'm also a bit in doubt if I haven't done something wrong, because it's very strange there is no other report of this issue. Maybe it's because the combination of joined inheritance, primary key column names which deviates from the main id name convention (which is 'id') and explicit locking isn't used that much?
We are experiencing the same problem when migrating from Hibernate 4.3.8 to 5.2.11. Thanks for reporting this. Does anyone know a workaround?
, I'm seeing the same failure in 4.2.21, 4.3.8, and 4.3.11, so your issue is probably different.
trying to see where we are for the next 5.3 release. You assigned this to yourself and scheduled as part of 5.3. Is this something you are going to work on in that time frame?
Fixed in master and 5.2 branches.
, thanks for the test and pointing out where the problem was!