-->
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: em.lock(OPTIMISTIC_FORCE_INCREMENT) not working?
PostPosted: Tue Oct 15, 2013 3:00 pm 
Newbie

Joined: Tue Oct 15, 2013 2:41 pm
Posts: 2
Hello everyone,

I am using Hibernate 4.1.4 as a JPA 2.x provider, within JBoss 7.1 using EJB 3.0 stateless session beans.

I have a JPA mapped entity that has been in use for some time in our application and works fine. I am attempting to change the entity to introduce an instance variable that bears the javax.persistence.Version annotation. This works fine, but I cannot get em.lock(object, LockModeType.OPTIMISTIC_FORCE_INCREMENT) to throw an OptimisticLockException as I find in the javadoc comments for EntityManager. In the broader sense, when I execute end user use cases that I would expect to induce an OptimisticLockException to occur, none are raised. So, I am trying to determine if my code is missing something, or if I have stumbled upon a defect in Hibernate 4.1.4. In my reading of the release notes in subsequent Hibernate versions, I do not find a defect noted that is what I am seeing.

So, lets say my JPA mapped entity looks like the following :

public class A {
// pre-existing instance variables here omitted for brevity.

@Version
private int readVersion;

// Methods omitted for brevity

public int getReadVersion() { return readVersion; }
public void setReadVersion(int newValue) { readVersion = newValue; }
}

Now say I do the following in an EJB 3.0 stateless session bean method that by default will use transaction attribute type of REQUIRED for container managed transaction :

A a = em.find(A.class, someId);
a.setReadVersion(5); // Even though readVersion in the database is say 12, just trying to force an OptimisticLockException
em.lock(a, LockModeType.OPTIMISTIC_FORCE_INCREMENT); // Should throw OptimisticLockException right now correct?

I do not see an exception thrown from the em.lock() call, and there is a call to em.flush() a few lines later and it does not raise an OptimisticLockException either.

Do you have an idea of how my code should be different so that Hibernate will in fact raise an OptimisticLockException or if this is a known issue or if it is known and addressed subsequent to Hibernate 4.1.4?

Thanks,

Doug


Top
 Profile  
 
 Post subject: Re: em.lock(OPTIMISTIC_FORCE_INCREMENT) not working?
PostPosted: Sat Oct 26, 2013 12:11 am 
Newbie

Joined: Tue Oct 15, 2013 2:41 pm
Posts: 2
For anyone out there that cares about this, I did find a solution that I will share. If any of you out there reading this know of a better way of handling this, please chime in.

It appears the primary problem is that Hibernate, and I expect really any JPA provider, expects that a JPA mapped instance variable that bears the @Version annotation is purely under the JPA provider's control and application code should not be meddling with that value.

Here is the case I am trying to solve. Two users of the system attempt to edit the same data item at the same time such that both have the same version when read (e.g. 4), but by the time the second end user attempts to save their changes to this data item, the version has already been updated to 5 in the database. Attempting to change the version by application code to 4 (the version number as read) prior to calling em.lock() is simply and unceremoniously ignored when that mutation happens against a managed object (one already present in the persistence context).

We are using the Open Session In View pattern, which basically means that since the Hibernate session is kept open for the duration of servicing an HttpRequest, all objects read are managed copies. The trick/hack that I found to work though was to detach the data item, reset its version to that which was known when the data item was read, and then reattach the data item via em.merge(). Turns out that if the managed copy's version is different than that housed in the database, Hibernate will raise an OptimisticLockException wrapped in an EJBTransactionRolledbackException.

Since that was what I was trying to induce all along, I find the above to be functionally correct. I just wish I could do this with far fewer moving parts (e.g. shipping the as read version from server to client back to server), as well as the detach/mutate read version/attach steps.


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.