Есть вот такой класс:
@Data
@Accessors(chain = true)
@NoArgsConstructor
@Entity
class MyEntity {
@JsonProperty(access = JsonProperty.Access.READ_WRITE)
@Id
private String id;
private String birthPlace;
@UpdateTimestamp
private LocalDateTime updatedAt;
@CreatedDate
private LocalDateTime createdAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
}
Написал тест таким образом:
String id = UUID.randomUUID().toString();
repository.save(new MyEntity().setId(id));
MyEntity savedEntity = repository.getOne(id);
assertNotNull(savedEntity.getCreatedAt());
assertNotNull(savedEntity.getUpdatedAt());
assertEquals(savedEntity.getCreatedAt(), savedEntity.getUpdatedAt());
Thread.sleep(100);
savedEntity = repository.save(repository.getOne(id).setBirthPlace("Moscow"));
assertNotNull(savedEntity.getCreatedAt());
assertNotNull(savedEntity.getUpdatedAt());
assertNotEquals(savedEntity.getCreatedAt(), savedEntity.getUpdatedAt());
В тесте выше repository - это JpaRepository. Проблема в том, что хук на PrePersist работает, а на PreUpdate не срабатывает. Не понимаю почему.
Если ты включишь логгирование SQL, то увидишь, что UPDATE-запрос не выполняется, поскольку никаких изменений в объекте savedEntity нет. Соответственно, @PreUpdate-хук тоже не вызывается.
Перед сохранением изменений Hibernate/JPA получает текущее состояние объекта из БД и сравнивает с сохраняемым объектом. Если они идентичны, то UPDATE-запрос не будет выполнен.
Перед вызовом savedEntity = repository.save(repository.getOne(id)); нужно изменить значение какого-либо свойства объекта savedEntity, тогда и запрос будет выполнен, и хук сработает.
Продвижение своими сайтами как стратегия роста и независимости