Issue Details (XML | Word | Printable)

Key: HHH-2366
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Critical Critical
Assignee: Steve Ebersole
Reporter: Rob Hasselbaum
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Hibernate Core

Changing a component's value does not trigger an update during flush

Created: 17/Jan/07 09:00 AM   Updated: 20/Jan/07 01:18 PM
Component/s: core
Affects Version/s: 3.2.1
Fix Version/s: 3.2.2

Time Tracking:
Not Specified

Environment: Hibernate 3.2.1, Oracle 10g


 Description  « Hide
If a value is changed in a persistent entity's component after a flush, no update is triggered on the next flush. The change is lost. For example, suppose we have two POJOs:

public class Person {
    private Long m_id;
    private int m_age;
    private Name m_name = new Name();
    ... getters and setters not shown ...
}

public class Name {
    private String m_lastName;
    ... getter and setter not shown ...
}

The POJOs are mapped as follows:

<class name="Person" table="tbl_person">
  <id name='id' column='objid'>
    <generator class='native'/>
  </id>
  <property name="age" column="age"/>
  <component name='name' class="Name">
    <property name="lastName" column="last_name"/>
  </component>
</class>

The following code demonstrates a loss of data:

Session sess = getSessionFactory().getCurrentSession();
Person p = new Person();
p.getName().setLastName("Smith");
sess.saveOrUpdate(p);
sess.flush();
p.getName().setLastName("Jones");
sess.flush();
p.getName().setLastName("Hill");
sess.flush();

// Reload from the database. We expect last name to be "Hill".
sess.evict(p);
p = (Person)sess.load(Person.class, p.getId());
String lastName = p.getName().getLastName();
assert "Hill".equals(lastName); // FAILS! Last name is still "Jones"!

The problem is that after the second flush, the "loadedState" of the entity in the session's persistence context contains a reference to the SAME instance of the component object as the entity itself. So when dirty checking is performed during the third flush, Hibernate is comparing the component object to itself, and the entity is not marked as dirty.

This is a regression from Hibernate 2, which updates correctly in this scenario.

 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Steve Ebersole added a comment - 20/Jan/07 01:07 PM
A previous fix incorrectly moved the deep-copy of the entity state (i.e. the loadedState) inside a particular 'if' block after an entity update where it should really have occurred regardless of that 'if' outcome.

Steve Ebersole added a comment - 20/Jan/07 01:18 PM
trunk / 3.2