-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Unchanged @ManyToOne record updates version at parent update
PostPosted: Fri Dec 11, 2009 8:35 pm 
Newbie

Joined: Tue Oct 09, 2007 11:53 pm
Posts: 5
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.


Top
 Profile  
 
 Post subject: Re: Unchanged @ManyToOne record updates version at parent update
PostPosted: Tue Dec 15, 2009 7:46 pm 
Newbie

Joined: Tue Oct 09, 2007 11:53 pm
Posts: 5
I'm not sure why, but our code was doing this:

Code:
private void save()
   {
   if(!entityManager.contains(parent)
      {
      log.info("enter child.version={0}", child.getVersion());
      parent = entityManager.merge(parent);
      log.info("merge child.version={0}", child.getVersion());
      entityManager.persist(parent);
      log.info("persist child.version={0}", child.getVersion());
      // Add some objects to a container
      entityManager.flush();
      log.info("flush child.version={0}", child.getVersion());
      }
   }
After the flush, child.version was incremented, even though it was untouched.

However, it doesn't make any sense to me to merge on an entity that the EntityManager doesn't contain. After removing that line, the child versions stopped getting incremented.

I am not the original author, who is no longer with the company. Is there a reason to merge an un-persisted entity? If not, why does it not throw an exception? Why would it update unmodified child objects?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.