Методы @RepositoryEventHandler, не вызываемые для методов @Modifying - PullRequest
0 голосов
/ 25 августа 2018

У меня есть класс обработчика событий следующим образом:

@Component
@RepositoryEventHandler(DonationOffer.class)
public class DonationOfferEventHandler {

    @Autowired
    DonationOfferNotificationService notificationService;

    @HandleAfterSave
    public void handleAfterSave(DonationOffer donationOffer){

        Integer donationOfferId = donationOffer.getDonationOfferId();
        System.out.println("updating donation offer");

        switch (donationOffer.getOfferStatus()){
            case Accepted:
                notificationService.generateAcceptedNotification(donationOfferId);
                break;
            case Rejected:
                notificationService.generateRejectedNotification(donationOfferId);
                break;
            case Cancelled:
                notificationService.generateCancelledNotification(donationOfferId);
                break;
        }
    }
}

И пружинное репо выглядит следующим образом:

@Transactional
public interface DonationOfferRepo extends PagingAndSortingRepository<DonationOffer,Integer>{

    @Modifying
    @Query(
            "update DonationOffer d " +
                    "set offerStatus = :offerStatus " +
                    "where d.donationOfferId = :donationOfferId"
    )
    @RestResource(path="updateStatus")
    int updateStatus(
            @Param("donationOfferId") Integer donationOfferId,
            @Param("offerStatus") OfferStatus offerStatus
    );
}

Обработчик события вызывается в случае запроса PUT, проблема в том, чтоМетод @HandleAfterSave не вызывается, когда я вызываю updateStatus (), т. Е.

a get request to /api/donationOffers/search/updateStatus?donationOfferId=45&offerStatus=Cancelled

Может ли кто-нибудь помочь, если я что-то упустил или это поведение по умолчанию, что @HandleAfterSave будет вызываться только с запросом PUT?

ОБНОВЛЕНИЕ: я создал метод для проверки обработчика событий с помощью метода сохранения репозитория следующим образом.Обработчик событий в этом случае также не вызывается.

@GetMapping(value="/savetest")
    @Transactional
    public ResponseEntity saveTesT(){
        DonationOffer donationOffer = donationOfferRepo.findOne(1);

        donationOffer.setOfferedBottles(donationOffer.getOfferedBottles()+1);

        donationOfferRepo.save(donationOffer);

        return new ResponseEntity(new StringWrapper("OK"), HttpStatus.OK);

    }

1 Ответ

0 голосов
/ 25 августа 2018

Чтобы вызвать событие из HandleBeforeSave, вам нужно выполнить запрос PUT.Если вы выполняете POST-запрос, то правильным обработчиком события будет HandleBeforeCreate.

ОБНОВЛЕНИЕ: я бы предположил, что метод слушателя не вызывается по той же причине, что и почему запросы не вызывают JPA prePersist, postPersist, preUpdate ... и так далее.Запросы имеют другой маршрут выполнения, как и для EntityManager.persis, update.Менеджер сущностей работает на основе идентичности, поэтому он может гарантировать, что сущность действительно была обновлена.То же самое нельзя сказать, когда вы используете запрос.Обычно менеджер сущностей выполняет один запрос для извлечения сущности, после чего он анализируется на предмет изменений, и тогда происходит ОБНОВЛЕНИЕ или не произойдет в случае отсутствия изменений.Не существует механизма, позволяющего определить, действительно ли произошло обновление при выполнении запроса.

Согласно документации @Modifying аннотация не гарантирует, что модификация действительно произойдет.Это гарантирует, что сеанс будет очищен после вызова метода.Причина этого заключается еще раз в том, что запросы имеют другой маршрут выполнения, чем обычные методы persist, merge, и вы не можете гарантировать, что сеанс сохранит целостность.Поэтому @Modifying гарантирует, что оно было очищено.

...