I've discovered what I consider to be an unexpected inconsistency in behavior:
Say you have an association which has no cascading options set, such as 'parent' in the example below:
Code:
@Entity
public class MyEntity {
private int id;
private MyEntity parent;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
@ManyToOne
@JoinColumn
public MyEntity getParent() {
return this.parent;
}
public void setParent(MyEntity parent) {
this.parent = parent;
}
}
Say you have object 'child' which refers to a transient 'parent':
Code:
MyEntity parent = new MyEntity();
MyEntity child = new MyEntity();
child.setParent(parent);
Now you persist the child using saveOrUpdate:
Code:
session.saveOrUpdate(child);
This succeeds. The parent is (correctly) not persisted, and the parent_id column on the child instance is set to null.
If, instead of using saveOrUpdate, you instead use merge:
Code:
session.merge(child);
...you get a TransientObjectException: "object references an unsaved transient instance - save the transient instance before merging"
(if you don't set the 'parent' association, 'merge' will successfully persist the child object.)
Question:
Is there a rationale for this difference in behavior? I.e., is there a reason 'merge' could not behave like 'saveOrUpdate', and simply leave leave the parent_id column 'null' for the child instance, not persisting the parent?
Hibernate version:
3.3.1
Thanks!
Aron