[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