This is in Hibernate 3.2.4 within JBoss Seam 4.2.2.
I have two @Entity objects (Parent and Child) with int @Version fields.
Code:
@Entity
public class Parent {
private Long id = null;
private int version = 0;
private Child child;
@Id @GeneratedValue
public Long getId() {
return id;
}
@SuppressWarnings("unused") //used only by hibernate via reflection
private void setId(Long id) {
this.id = id;
}
@Version
@SuppressWarnings("unused") //used only by hibernate via reflection
private int getVersion() {
return version;
}
@SuppressWarnings("unused") //used only by hibernate via reflection
private void setVersion(int version) {
this.version = version;
}
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH},
fetch = FetchType.LAZY)
@JoinColumn(nullable = false)
@org.hibernate.annotations.ForeignKey(name = "fk_Parent_Child")
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
}
Code:
@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true) // faster updates and inserts
public class Child {
private Long id = null;
private int version = 0;
@Id @GeneratedValue
public Long getId() {
return id;
}
@SuppressWarnings("unused") //used only by hibernate via reflection
private void setId(Long id) {
this.id= id;
}
@Version
@SuppressWarnings("unused") //used only by hibernate via reflection
private int getVersion() {
return version;
}
@SuppressWarnings("unused") //used only by hibernate via reflection
private void setVersion(int version) {
this.version = version;
}
}
This is not bidirectional. The Child object does not have a List of Parent objects.
When the Parent object is updated, the version count on the Child object gets updated. This is causing an OptimisticLockException when two Parent objects are created/modified at the same time that refer to the same Child object, even though the Child object is unmodified.
Is this expected behavior? I thought Hibernate did "dirty" checking. Do I need to include "selectBeforeUpdate = true" to prevent this from happening? That sounds like a performance hit I'd rather not incur.