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.