[hibernate-issues] [Hibernate-JIRA] Created: (HHH-6981) Inconsistent handling of @Embedded objects wrt null attributes
Maxime Gamboni (JIRA)
noreply at atlassian.com
Wed Jan 18 08:22:09 EST 2012
Inconsistent handling of @Embedded objects wrt null attributes
--------------------------------------------------------------
Key: HHH-6981
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6981
Project: Hibernate ORM
Issue Type: Bug
Components: annotations, core
Affects Versions: 3.6.9
Environment: Discovered in Hibernate 3.6.2, verified against Hibernate 3.6.9. Database platform probably irrelevant? (Verified against Oracle JDBC and H2)
Reporter: Maxime Gamboni
First of all, I have to say I am not yet very fluent in Hibernate. I started working on a pre-existing codebase so some subtleties of this are surely escaping me and this is also the reason I might have trouble creating a test case for this bug. I was also not sure which Components to select in this bug report.
Say I have a class A with an @Embedded component B b.
Step 1:
If I saveOrUpdate an instance A a such that:
1) a.b is not null
2) All attributes of a.b.xyz are null
3) All other attributes a.xyz (except from the identifier in case of an update) are null:
This produces a row in the database with all attributes set to null.
Step 2:
If I then attempt to update the object with a separate invocation of saveOrUpdate where a.b is still not null but values of other attributes are irrelevant, Hibernate will execute an insert instead of an update, causing a "Unique index or primary key violation".
I tracked this down to the org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert method:
In step 1, fields contains a non-null B instance, so isAllNull( fields, j ) returns false, so the row is updated with all null values. It is NOT deleted.
In step 2:
1) The oldFields array contains only null values (including the 'b' attribute), causing isAllNull( oldFields, j ) to return true.
2) oldFields itself is not null (in my case, A was part, but not embedded, in another entity that had non-null values for fields outside of table 'j'. Is this relevant?).
This causes the first test to return true, and sets isRowToUpdate to true, so we invoke the insert() method, which fails as we already have a row with the same identifier.
My workaround was to make sure my objects never contain an instance of B whose attributes are all null but this is not ideal. Dropping the test
if ( isNullableTable( j ) && oldFields != null && isAllNull( oldFields, j ) ) isRowToUpdate = false;
would probably solve the problem, but probably at the cost of a lesser efficiency in other cases.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list