Use Integer Version Instead of Timestamp for Optimistic Locking

ID

java.hibernate_version_not_timestamp

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

best-practice, hibernate, reliability

Description

Reports @Version-annotated fields whose type is a timestamp or date type (Timestamp, Date, Calendar, Instant, LocalDateTime, OffsetDateTime, ZonedDateTime) instead of an integer type. Timestamps are less reliable than integer counters for optimistic locking.

Rationale

Optimistic locking with a timestamp relies on millisecond granularity. Two concurrent transactions that load and update the same entity within the same millisecond can silently bypass the lock. Additionally, system clock adjustments (daylight saving time, NTP corrections) can cause version comparisons to produce incorrect results. An integer counter increments deterministically and is immune to clock-related issues.

// Bad: timestamp-based version
@Entity
public class Order {
    @Version
    private Timestamp version; // vulnerable to clock skew
}

Remediation

Change the @Version field to an integer type (int, long, Integer, or Long). If migrating an existing database, alter the version column’s SQL type accordingly.

// Good: integer-based version
@Entity
public class Order {
    @Version
    private long version; // deterministic, clock-independent
}