AbstractEntityPersister swallows JDBCExceptions in processGeneratedProperties
-----------------------------------------------------------------------------
Key: HHH-2503
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2503
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1, 3.2.2, 3.2.3
Environment: 3.2.2GA and trunk
Reporter: Dag Liodden
Seems to be a small typo on line 3718 in AbstractEntityPersister (trunk and 3.2.2 GA)
which makes exceptions during property generation being logged but not thrown:
catch( SQLException sqle ) {
JDBCExceptionHelper.convert(
getFactory().getSQLExceptionConverter(),
sqle,
"unable to select generated column values",
selectionSQL
);
There should be a throw in there I guess. :)
catch( SQLException sqle ) {
throw JDBCExceptionHelper.convert(
getFactory().getSQLExceptionConverter(),
sqle,
"unable to select generated column values",
selectionSQL
);
This bug will not be noticeable in most cases and is probably why it hasn't been
detected / fixed so far. The method in question (processGeneratedProperties) is used for
retrieving properties that are marked as "generated" in the mapping document /
annotations - in other words any value that the database provides and is considered
"read-only" from the Hibernate application's point of view.
The generated value is retrieved by an extra select statement executed by Hibernate after
an entity has been inserterd and / or updated (according to how the generated property is
flagged). In my particular case, a property (not a key) is marked as
generated="insert", so after Hibernate inserts a new entity to the database, it
will immediately do a select and set the generated property to the value the database
returns.
Only in rare cases will this select fail in any way - in fact, I cannot think of any
situations other than mapping errors (e.g getInt on a CHAR column) that can cause errors
in this last select. That is in addition to my situation - a deadlock.
My entity class uses uuid.hex generator for the PK, but at one point, we introduced a
second unique key due to purely aestethic reasons. This is a SQL Server identity column.
Since we don't do any explicit table locking during the inserts, we end up with
deadlocks every time the following happens:
T1: INSERT INTO TABLE (ID) values (?)
T2: INSERT INTO TABLE (ID) values (?)
T2: SELECT GENERATED_ID FROM TABLE WHERE ID = ? -- T1's insert hasn't been
committed, so what should the the generated ID be? Deadlock!
T1: SELECT GENERATED_ID FROM TABLE WHERE ID = ?
...
SQL Server throws an error to indicate the deadlock, but due to the missing throw in the
processGeneratedProperties-method, it is never shown to the process doing the insert. The
generated property is not set and retains it's null (or 0 in case of a primitive)
without the business logic ever knowing that the entity could not be saved.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira