Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Retyring after StaleObjectStateException in a batch process
PostPosted: Thu Apr 13, 2017 5:50 am 
Newbie

Joined: Tue Feb 23, 2016 1:04 pm
Posts: 11
Hibernate version : 3.2.6.ga

Spring(transactions) : 3.1.1

I am facing this in a batch process where I don't have to notify any end user ,just need to reload the entities involved & redo the work.

However, even after catching the StaleObjectStateException & reloading the entity, I am still running into StaleObjectStateException..why is that?

More details on how I am reproducing this is after the code...

Code:
   
@RequestMapping("testConcurrent/{entityId}/{version}")
    @GET
    @Transactional
    public void testConcurrent(@PathVariable("entityId") Integer entityId,
            @PathVariable("version") Integer version){

        try{
        updateData(entityId, version);
        sessionFactory.getCurrentSession().flush();
        }
        catch(StaleObjectStateException|OptimisticLockException e){
            LOG.info("retrying due to concurrency error");
            updateData(entityId, version);
        }
        catch(Exception e){
            LOG.info("some other error");
        }
    }


    public void updateData(Integer entityId, Integer version) {
        Entity entity = entityDAO.getEntityById(entityId);
        entity.setUpdated(DateUtils.getCurrentTime());
            entity.setVersion(version.longValue());

            entityDAO.createOrUpdateEntity(crp);
    }




How i reproduce concurrency:

1)I call testConcurrent for a given object with some version, i stop the debug flow at the last line in updateData method.

2)Then I call testConcurrent again for the same object with some other version, and finish the flow. This reflects in the DB instantaneously as i have a flush() after this method returns.

3)Now when i continue the first thread(which was blocked in step 1), it throws this StaleObjectStateException as expected & it gets caught, calls the updateData method again , but now when i fetch the object from DB(entityDAO.getEntityById); it throws the same StaleObjectState exception again. Why should it when i am reloading the latest object from database?

This is the exception stacktrace by the way , Could not synchronize database state with session org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):


Top
 Profile  
 
 Post subject: Re: Retrying after StaleObjectStateException in a batch
PostPosted: Thu Apr 13, 2017 6:09 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1172
The transaction boundaries are probably wrongly set. I also suspect an Open Session in View Anti-Pattern here since you call the Session in your Web layer:

Code:
sessionFactory.getCurrentSession().flush();


You need to fix that first. Remove the Open Session in View Filter and rely on the @Transactional boundaries set at the Spring Service level.

Now, back to the OptimisticLockingException. Don't do it in a try/catch block in your web layer. You need to leverage some AOP for that. But, you're in luck! Just follow the steps in this article. The whole code is already available on Maven Central, so you just need to add this dependency to your project:

Code:
<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>db-util</artifactId>
    <version>0.0.1</version>
</dependency>

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 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.