Issue
I'm using Spring boot 2.7.0
And have the next entities in simple:
@Getter
@Setter
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Long version;
private String name;
}
@Getter
@Setter
@Entity
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
Account account;
private String message;
}
and jpa repositories:
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
}
@Repository
public interface EventRepository extends JpaRepository<Event, Long> {
Page<Event> findAllByAccount(Account account, Pageable pageable);
}
In short I call
eventRepository.findAllByAccount(accountRepository.findById(1), PageRequest.of(1,10));
Problem is every call of last code increases the version field of Account
by 1. So question is why? I don't call any update or save method.
And additionally the result of this behaviour is calling of method needs
@Transactional(readonly=false)
Otherwise if I write readonly=true
that throws cannot execute UPDATE in a read-only transaction
ADDED:
full code of usage:
@Transactional
public Page<Event> events(Long accountId, int page) {
return eventRepository.findByAccount(findById(accountId), PageRequest.of(page, PAGE_SIZE));
}
@GetMapping("/events")
public List<EventResponse> listEvents(@RequestParam(value = "max", defaultValue = "0") int page) {
return eventService.events(1L, page).stream().map(EventResponse::of).toList();
}
Solution
It looks like hibernate is deriving lockMode type as either of WRITE
or OPTIMISTIC_FORCE_INCREMENT
or PESSIMISTIC_FORCE_INCREMENT
based on isolation level of your database. As per reference hibernate decides this pessimistic locking by its own based on database you use.
As per doc, if lockmode type is either of what I mentioned above, Version
will get automatically incremented even if you haven't changed anything i.e. even if you haven't do any update or save.
Please check database isolation level & based on that you might get an idea about this.
Edit: as you explicitly setting lockmode as write so my answer validates that because of WRITE mode, your version got incremented automatically.
Answered By - Ashish Patil
Answer Checked By - Marilyn (JavaFixing Volunteer)