Обновит ли метод save() Spring Data объект в базе данных, если в объекте нет изменений?

#spring #hibernate #spring-data-jpa #spring-data #hibernate-mapping

#spring #спящий режим #spring-data-jpa #spring-данные #hibernate-отображение

Вопрос:

При редактировании формы пользователь может иногда не изменять форму и по-прежнему нажимать кнопку отправки. В одном из методов контроллера, приведенных ниже, будет ли метод save () выполнять запрос к базе данных и обновлять поля, даже если пользователь ничего не изменил?

 PostMapping("/edit_entry/{entryId}")
public String update_entry(
        @PathVariable("entryId") Long entryId,
        @RequestParam String title,
        @RequestParam String text
) {
    Entry entry = this.entryRepo.findById(entryId).get();
    
    if (!entry.getTitle().equals(title))
        entry.setTitle(title);
    if (!entry.getText().equals(text))
        entry.setText(text);
        
    this.entryRepo.save(entry);
        
    return "redirect:/entries";
}
  

А также, необходимы ли в этом случае инструкции «if»?

Комментарии:

1. entryRepo Расширяет ли JpaRepository или CrudRepository?

2. entryRepo расширяет CrudRepository.

3. если да, то нет. Обновление если ничего не изменится, jpa предотвратит это и не выдаст инструкцию (если у вас нет динамически вычисляемых полей, таких как последняя обновленная временная метка). Также вы Optional неправильно используете. Не используйте get (если не найдено, произойдет сбой), используйте map вместо этого.

4. @M. Deinum Спасибо! Я определенно рассмотрю возможность использования map вместо `get’!

Ответ №1:

Что именно происходит во время вызова save(…) зависит от подчиненной технологии сохранения. По сути, существует две категории реализаций:

  1. Реализации, которые активно управляют объектами.Примерами этого являются JPA и Neo4j. Эти реализации отслеживают объекты, возвращаемые из хранилища, и, таким образом, способны обнаруживать изменения в первую очередь. Вы платите за это дополнительной сложностью, поскольку объекты обычно каким-то образом инструментируются, и обнаружение изменений, конечно, также требует времени, даже если в итоге никаких изменений не обнаружено. С другой стороны, единственный триггер обновляется при необходимости.

  2. Реализации, которые активно не управляют объектами.Примерами являются JDBC и MongoDB. Эти реализации не отслеживают объекты, загруженные из хранилища данных, и, следовательно, не обрабатывают их. Это также означает, что нет способа обнаружить изменения, поскольку вся реализация видит экземпляр объекта без какого-либо дополнительного контекста.

В вашем конкретном примере реализация MongoDB все равно будет выдавать обновление, в то время как JPA вообще не будет выдавать обновление, если параметры запроса не содержат отличающихся значений.

Комментарии:

1. Итак, как я понимаю, говоря о 1-й категории реализаций, операторы «if» не сделают процесс каким-то образом быстрее, потому что строка this.entryRepo.save(entry); все равно будет выполнена…

2. Но если я добавлю логическую переменную, например, boolean changed = false; прямо над серией операторов «if», чтобы переменная была преобразована в true блок «if», в котором было изменено поле, тогда я this.entryRepo.save(entry); добавлю блок «if», который будет выполнен, если changed переменная сохранит true значение (то естьбыли замечены некоторые изменения) будет ли быстрее обнаруживать изменения или наличие этих операторов «if» просто бесполезно?