tokosh
tokosh

Reputation: 1836

Grails: Testing Optimistic Locking

Using Grails 2.3.9

I am currently trying to test the optimistic locking in Grails. The documentation says,

When you perform updates Hibernate will automatically check the version property against the version column in the database and if they differ will throw a StaleObjectException

In the integration test, I have something like:

def existingGroup = new Group("Group")
    .save(flush: true, failOnError: true)

def groupA = Group.get(existingGroup.id)
def groupB = Group.get(existingGroup.id)

groupA.name = "Group A"
groupA.save(failOnError: true, flush: true)

groupB.name = "Group B"
groupB.save(failOnError: true, flush: true)

The exception is, however, never thrown. So, I guess, I'm doing something wrong with the session/flushing. But all permutations (using flush and not) on that had no change. I would like to see that this exception is thrown.

I also tried resetting the version to 0, without success (groupB saved as usually).

Am I doing something wrong?

Upvotes: 3

Views: 865

Answers (1)

micha
micha

Reputation: 49552

The problem with your approach is that groupA and groupB refer to the same managed (attached to the hibernate session) domain object.

If you print the versions after groupA.save() you can see that the version of groupB also changed.

You can create an optimistic locking error by creating a new transaction manually:

def groupA = Group.get(123)

Group.withNewTransaction {
  def groupB = Group.get(123)
  groupB.name = "Group B"
  groupB.save(failOnError: true, flush: true)
}

groupA.name = "Group A"
groupA.save(failOnError: true, flush: true) // should fail

Here groupB is retrieved, modified and committed in another transaction. groupA still uses the old version so the save operation on groupA should fail.

Note that you have to use withNewTransaction and not withTransaction. With withTransaction the created transaction would participate in the transaction that is used for the integration test. So the behaviour would be the same as without any manual transaction block.

Upvotes: 3

Related Questions