Home > Enterprise >  How to unlock (re-load current state) in optimistic locking?
How to unlock (re-load current state) in optimistic locking?

Time:12-04

I have an entity with optimistic locking:

@Version
private Integer version;

I do a get request by id which performs a findById in the backend. I use the id to perform an update using PUT method which performs a save in the backend. After that I do the get again to get the modified object back: After that I try to update it again and get:

{
    "timestamp": {
        "nano": 305933000,
        "epochSecond": 1638524115
    },
    "status": 500,
    "error": [],
    "type": "ObjectOptimisticLockingFailureException",
    "path": "uri=/rooms/",
    "message": "Internal Server Error"
}

Why do I get that error? The first update transaction should be done, shouldnt it? How can I unlock the entity?

I do not use EntityManger. I use JpaRepsoitory with save method.

EDIT

If I provide the version as an attribute in the get call and set the version into the entity which im saving it works.

Is this the way you usually do it? That the client has to provide the latest version of the entity which should get updated?

CodePudding user response:

You aren't going to get the exception until the save is executed in the database, and your save doesn't happen immediately, remember it uses transactional write-behind.

If your flush mode is AUTO, which is the default for JPA, then the save doesn't get pushed to the database until your second findById, that counts as running a query so any updates have to be flushed first. Once the update executes, the version comparison happens, JPA realizes no row was updated and it throws the optimistic locking exception.

BTW when you say you're not using an EntityManager: you're not using one directly but there is still one involved, the JPA repository is using one. All this stuff of stashing updates and deciding when to push them is done by an EntityManager. It also caches the result of running queries.

When you say current state, there are several states. There is the state of the entity manager, then there's the state of the transaction in progress, then there is the state of the database with committed changes. The EntityManager uses the flush mode to decide when to sync up its own 1st level cache state with the transaction in progress.

And yes you have to give the entity being updated the latest version number, that is what is getting compared.

  • Related