2017-02-20 12 views
0

Я использую jpa EntityListners аннотацию для прослушивания событий, когда объект обновляется. Проблема заключается в аннотациях @PostPersist и @PostUpdate, которые запускают это событие как на commit, так и на flush. И в моем коде im использует flush перед фиксацией (не может изменить эту логику/не может удалить флеш-вызов). Пример моего кода:Как публиковать только события onCommit от сущностей?

@Transactional 
public void updateValue(int id, String value) throws ServiceException { 
     try { 
      BusinessEntity bEntity = businessRepository.findById(id); 
      bEntity.setValue(value); 
      businessRepository.merge(trip); 

      //First event is fired 
      businessRepository.flush(); 


      someService.performLogicThatUpdatesBusinessEntityAgain(); 

     } catch (DatabaseException e) { 
      throw new ServiceException(e); 
     } 
//transaction is committed and hence Second event is fired 
} 

Это приводит к тому, что оба события срабатывают слишком близко друг к другу. И с разными значениями сущности. Что происходит в большом объеме, то происходит последовательность событий. Слушатель сущности также публикует событие в очередь. И потребитель читает dto объекта и сохраняет/обновляет в no-sql. Могу ли я избежать флеш-события? Так что я могу получить только объект за транзакцию?

ответ

0

В соответствии со спецификацией JPA, обратные вызовы @PostPersist и @PostUpdate происходят после операций вставки/обновления базы данных. Это означает, что они будут выполняться после каждого «релевантного» флеша (в вашем случае после явного сброса после вызова merge и неявного при совершении транзакции).

Вы уверены, что изменить логику невозможно, чтобы избежать явного флеша? В коде, который вы показали, объединенный объект уже имеет идентификатор, нужны ли вам какие-либо другие побочные эффекты?

На самом деле это не обходное решение, но, возможно, вы можете использовать некоторую условную логику в обработчике событий на основе состояния объекта, который изменяется после явного флеша?