
|
If you were logged in you would be able to see more operations.
|
|
|
|
Environment:
|
Hibernate 3.2.1, Oracle 10g
|
|
|
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.
|
|
Description
|
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. |
Show » |
|