Отношения между OSIV и JPA Entity Listener @PreUpdate - PullRequest
1 голос
/ 21 января 2020
User user = userRepository.findOne(1);
user.age = user.age + 1; // user.age value modify
userService.updateUser(user);
@Transactional
class UserService {
   public void updateUser(User user) {
      productRepository.findByName("AAA"); // (1)
      userRepository.save(user); // (2)
   }
}
@Entity
@EntityListener(UserListener.class)
class User {...}
class UserListener{
   @PreUpdate
   public void onPreUpdate() { ... }
}

Когда OSIV = true, (1) строка -> @PreUpdate вызывается / (2) строка -> @PreUpdate вызывается

Когда OSIV = false, (1) строка -> @PreUpdate не вызывается / (2) строка -> @PreUpdate вызывается

Почему это происходит? Почему @preupdate вызывается при выполнении (1) строки?

1 Ответ

1 голос
/ 21 января 2020

Вот спецификация JPA 2.0:

Обратные вызовы PreUpdate и PostUpdate выполняются до и после операций обновления базы данных для данных объекта соответственно. Эти операции с базой данных могут происходить во время обновления состояния объекта или могут происходить во время сброса состояния в базу данных (что может быть в конце транзакции).


Помните, что @ PreUpdate всегда будет запускаться для всех транзакций чтения / записи из-за FlushMode для транзакций чтения / записи и никогда не для транзакций только для чтения (из-за FlushMode.NEVER)

Без OSIV

Когда вы звоните updateUser, тогда у вас есть транзакция чтения / записи (внешняя) из-за @Transactional.

Теперь findByName является транзакционным, но помечается как только для чтения (по умолчанию все средства поиска только для чтения ). Текущая транзакция приостановлена, и выполняется новая readonly . Вот почему (1) строка не вызывает @Preupdate.

. После этого текущая транзакция чтения / записи возобновляется (save не только для чтения), и @Preupdate срабатывает.


С OSIV

В этом случае существует только одна транзакция чтения / записи, связанная с текущим запросом. findByName выполняется в транзакции чтения / записи, поэтому (1) строка вызывает @ Preupdate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...