..updating a previously saved (parent) object in the same session the first time.
Hey folks,
i observed a strange behaviour and i'm thinking it is a bug, but maybe someone has an explanation.
I've a simple one-to-many mapping and following steps i made.
-create a parent, add a children
-save the parent
-substitute the children
-update the parent (still the same session)
-flush and close the session
Then i've one saved parent but two children instead of one.
I observed this behaviour in my application and try to reproduce it with a simple scenario.
the test code
Code:
public void testParentChildren() throws Exception {
int max = 2;
Session session = HibernateSessionThreadLocal.currentSession();
Parent parent = new Parent();
Children[] children = new Children[max];
for (int i = 0; i < max; i++) {
if (i > 0)
parent.removeChildren(children[i - 1]);
children[i] = new Children();
children[i].setString(Integer.toString(i));
parent.addChildren(children[i]);
session.saveOrUpdate(parent);
}
HibernateSessionThreadLocal.closeSession();
}
After the execution, 2 childrens are persistet.(instead of 1)
But this duplicate saving just happens the first time, if i increase
max also 2 childrens getting persistet.
The use of saveOrUpdate() or save(), update() is no consideration.
If i call session.refresh(parent) after saving it the first time everything works perfect and just one children is persistet.
mappings
Code:
<hibernate-mapping>
<class
name="org.weta.jas.agent.Parent"
table="Parent"
>
<id
name="uniqueSequence"
column="uniqueSequence"
type="long"
unsaved-value="null"
>
<generator class="native">
</generator>
</id>
<set
name="Children"
lazy="false"
inverse="true"
cascade="all-delete-orphan"
>
<key column="fkParent"/>
<one-to-many class="org.weta.jas.agent.Children"/>
</set>
</class>
</hibernate-mapping>[code][/code]
<hibernate-mapping>
<class
name="org.weta.jas.agent.Children"
table="Children"
>
<id
name="uniqueSequence"
column="uniqueSequence"
type="long"
unsaved-value="null"
>
<generator class="native">
</generator>
</id>
<property
name="string"
type="java.lang.String"
column="String"
/>
<many-to-one
name="Parent"
column="fkParent"
not-null="true"
/>
</class>
</hibernate-mapping>
classes
Code:
public class Parent {
private Long uniqueSequence;
protected Set children;
public Parent() {
children = new HashSet();
}
public Long getUniqueSequence() {
return uniqueSequence;
}
public void setUniqueSequence(Long puniqueSequence) {
uniqueSequence = puniqueSequence;
}
public Set getChildren() {
return children;
}
public void setChildren(Set pset) {
children = pset;
}
public void addChildren(Children pChildren) {
pChildren.setParent(this);
children.add(pChildren);
}
public void removeChildren(Children pChildren) {
if(children.contains(pChildren))
children.remove(pChildren);
}
}
Code:
public class Children {
private Long uniqueSequence;
private Parent parent;
private String string;
public Long getUniqueSequence() {
return uniqueSequence;
}
public void setUniqueSequence(Long puniqueSequence) {
uniqueSequence = puniqueSequence;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent pParent) {
parent = pParent;
}
public String getString() {
return string;
}
public void setString(String string) {
this.string=string;
}
}
hibernate 2.1.1 + 2.1.2