@RepositoryEventHandler方法没有为@Modifying方法调用

问题描述 投票:1回答:1

我有一个事件处理程序类,如下所示:

@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请求的情况下调用事件处理程序的问题是当我调用updateStatus()时没有调用@HandleAfterSave方法,即

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

如果我遗漏了某些东西可以帮助任何人,还是只有PUT请求才能调用@HandleAfterSave的默认行为?

更新:我已经创建了一个使用repo save方法测试事件处理程序的方法,如下所示。在这种情况下也不会调用事件处理程序。

@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);

    }
spring hibernate spring-mvc transactions spring-data-rest
1个回答
2
投票

要从HandleBeforeSave触发事件,您需要执行PUT请求。如果您正在执行POST请求,那么正确的事件处理程序将是HandleBeforeCreate。

更新:我猜测侦听器方法不会被调用的原因与查询为什么不调用JPA prePersist,postPersist,preUpdate ......等事件相同。对于EntityManager.persis,update,查询具有不同的执行路径。实体经理在身份的基础上工作,因此它可以保证实体实际上已经更新。使用查询时无法告知相同内容。通常,实体管理器将执行一个查询以获取实体,而不是分析更改,然后UPDATE将发生,或者在没有更改的情况下不会发生。没有机制可以判断执行查询时是否确实发生了更新。

根据文档@Modifying注释并不能保证实际发生修改。保证的是会话将在方法调用后被清除。这背后的原因是,查询具有与正常持久化,合并方法不同的执行路由,并且您无法保证会话将保持完整性。因此@Modifying将保证它已被清除。

© www.soinside.com 2019 - 2024. All rights reserved.