Не срабатывает PreUpdate в Spring Data

116
23 ноября 2019, 00:00

Есть вот такой класс:

@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 не срабатывает. Не понимаю почему.

Answer 1

Если ты включишь логгирование SQL, то увидишь, что UPDATE-запрос не выполняется, поскольку никаких изменений в объекте savedEntity нет. Соответственно, @PreUpdate-хук тоже не вызывается.

Перед сохранением изменений Hibernate/JPA получает текущее состояние объекта из БД и сравнивает с сохраняемым объектом. Если они идентичны, то UPDATE-запрос не будет выполнен.

Перед вызовом savedEntity = repository.save(repository.getOne(id)); нужно изменить значение какого-либо свойства объекта savedEntity, тогда и запрос будет выполнен, и хук сработает.

READ ALSO
JavaFX 11 javafx.embed.swing does not exist

JavaFX 11 javafx.embed.swing does not exist

Есть проект на OpenJDK11 + OpenJFX11Запускал через Maven, но необходимо перейти на Gradle

129
Как протестировать удаление объекта в JUnit?

Как протестировать удаление объекта в JUnit?

нужно протестировать функцию Food eat() в JUnit: убедится в том, что функция всё же удалила объект из списка

126
Как указать файл для логирования во время runtime?

Как указать файл для логирования во время runtime?

Я пользуюсь log4j и мне нужно указать файл для логирования во время runtimeПодскажите пожалуйста как мне это сделать

99