Search code examples
javaspring-dataoptimistic-locking

Optimistic lock failure when @Version is null


I am working on some code to generate serial numbers. I will read and update a record in the database which holds the next number to generate. As I expect to have different threads accessing this record I just added the @Version label to a Timestamp field of the same entity and then control the OptimisticLockExceptions that could rise.

Also I would have several records like these in my database holding different serial numbers, they can be created or deleted depending on the business.

The domain object looks like this:

@Entity
@Table(name="Preferences")
public class Preferences implements Serializable, DomainObject {
...
...
@Column(name="nextSerial")
private String nextSerial;

@Version
@Column(name="RefreshDate")
private Timestamp refreshDate;
...

Until here everything works fine, the problem comes when another application that shares the same data creates a Preferences record. When this application was built, the @Version column didn't exist so it will create the record with a Null value as refreshDate.

I am aware of this and I try to set a refreshDate and update the record, also tried to delete and create again the record but in any case, I will get an Exception like the next:

org.springframework.orm.jpa.JpaOptimisticLockingFailureException: Exception [EclipseLink-5001] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: An attempt was made to delete the object [com.core.domain.Preferences@5e092f04], but it has no version number in the identity map.

So my question is, how can I handle this problem from my application?. Using triggers in the database to ensure a non null @Version is not desirable, also changing the other application isn't desirable either.


Solution

  • Can you set a default value for refreshDate at creation time using DB means? Like

    VERSION BIGINT NOT NULL DEFAULT 1 -- for a numeric version

    RefreshDate TIMESTAMP NOT NULL DEFAULT now() - for your case