Im trying to update an student on db, however, since cache its executed before transaction already finish, cache its keeping the old version value. So on next update misaligned of version field makes hibernate fail.
Steps to reproduce:
First, persist a new student, db and cache are aligned, because field version its long to take
Zero by default.
Second update student, cache its execute and then transaction finish so framework update version field on db, however, keeps old value.
Third, update student so when service do findById it take value from cache and when tries to save it hibernate complains about misaligned of version field.
@Transactional
public StudentModel update(final StudentModel studentModel, final UUID id) {
return studentRepository.findById(id)
.map(s -> s.withName(studentModel.getName()))
.map(studentRepository::save)
.orElseThrow(RuntimeException::new);
}
@Transactional(readOnly = true)
@CacheConfig(cacheNames = StudentRepository.MIDS)
public interface StudentRepository extends JpaRepository<StudentModel, UUID> {
String MIDS = "mids";
@Override
@CachePut(key = "#result.id")
@Modifying
@Transactional
StudentModel save(StudentModel entity);
}
@Entity
@Getter
@Setter
@ToString
@Builder
@Table(name = "student")
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class StudentModel implements Serializable {
private static final long serialVersionUID = -5568414877301936922L;
@Id
@GeneratedValue(generator = "UUID")
private UUID id;
private String name;
@LastModifiedDate
private Instant lastModifiedDate;
@CreatedDate
private Instant createdDate;
@Version
private Long version;
public StudentModel withName(final String name) {
this.name = name;
return this;
}
}
Is there a way to modify secuencial flow execution of transaction and cache?
NOTE: all code could be found here: https://github.com/nekperu15739/audit_and_cache/tree/main