Announcement Announcement Module
Collapse
No announcement yet.
Optimistic locking with Hibernate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Optimistic locking with Hibernate

    Hi

    I am currently stuck on this Optimisitc locking feature provided by hibernate which doesn't seem to work for me.

    I have a Domain Object ( DO ) and a Data Transfer Object(DTO) and a property called recordVersion on both of these objects and its defined in the *.hbm file with <version ....> property.

    Problem is this:
    I read the DO and convert it to DTO and hibernate session closes. DTO then gets passed on to the web layer where user modifies it.

    Then when the form is submitted, i read the Domain object from database and convert the DTO to DO.
    Which means that if the DTO has the version value = 10 for example thats what the version value on the Domain object would be in the session now after copying DTO properties onto the Domain Object.

    But in the database the version value of the Domain object is for example 12,
    when i save my DTO that had version value= 10 i would expect hibernate to throw StateObjectStateException but doesn't seem to happen.

    What happens is the version value becomes 13 instead.

    Any ideas what is going wrong ?

  • #2
    Originally posted by ozGuy View Post
    Hi

    I am currently stuck on this Optimisitc locking feature provided by hibernate which doesn't seem to work for me.

    I have a Domain Object ( DO ) and a Data Transfer Object(DTO) and a property called recordVersion on both of these objects and its defined in the *.hbm file with <version ....> property.

    Problem is this:
    I read the DO and convert it to DTO and hibernate session closes. DTO then gets passed on to the web layer where user modifies it.

    Then when the form is submitted, i read the Domain object from database and convert the DTO to DO.
    The identity of the DO (Entity) is not enough to make it truly unique. What you need to do is add the version: the id + the version identifies an entity at a specific point in time.

    If you load the entity from the database, you have to add the id and the version:

    so:

    Entity e = doa.load(id,version)

    if the entity is null, you know that the object has been changed (or removed) so you can thrown an optimistic locking failure.

    After the entity has been loaded, you can transport the other properties to the entity from the DTO.

    Comment


    • #3
      Sounds like a solution but i cant see that working properly when certain objects in the object graph as shared among different entities.

      Example:
      I have 2 parent object A and B which contains links to C D and E object.
      A -->C-->D
      B -->D

      Object D is used by both A and B instances.

      And all the collections and linked entities of A and B are lazily fetched by hibernate.
      Doing dao.load(id,version) will only work for A and B.

      So if 2 different users have A and B with its complete object graph, user A saves first which causes the version numbers on the A,C and D to be incremented.

      Now user 2 saves B which also needs to update D but the version number of the D has been already modified and i need to trap this aswell. So at this point no update should occur and OptimisticLocking exception needs to be thrown.

      How to i specify the version number column to be used aswell during load for linked entities in Hibernate ?

      Comment


      • #4
        Hi,

        I am facing a problem that is related to OptimisticLocking exception nested with StaleObjectStateException. This is occurring when i m reading a versioned entity from DB under @transaction context.
        I found that there is an open bug in Hibernate Jira https://hibernate.onjira.com/browse/HHH-5867
        which states ---->

        On a special constellation hibernate increases the internal used version of an entity on a read operation. For example if you save an entity the version is initial set. If you execute a query to read the entity afterwards, the version increases on this read. Please notice that the entity has NOT changed in the meantime. An update of the version must not happen here.
        This problem seems to occur only if you have a few prequisites:
        1. An entity, which has a component or subclasses
        2. The component/subclasses must use an custom usertype
        3. The read operation is covered by transaction -----> This is my case.
        The bug leads to StaleObjectStateExceptions in production because the version has changed after a read operation by another thread.


        The issue i am facing now is my service layer is annotated with @Transactional to avoid LazyInitializationException and due to this Transaction the version number of the entity is getting updated on every read operation.

        I would really appreciate your suggestion/comments on this. This is an issue in production so please help me.

        Thanks and regards,
        Chandan

        Comment

        Working...
        X