我有一个事件处理程序类,如下所示:
@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);
}
要从HandleBeforeSave触发事件,您需要执行PUT请求。如果您正在执行POST请求,那么正确的事件处理程序将是HandleBeforeCreate。
更新:我猜测侦听器方法不会被调用的原因与查询为什么不调用JPA prePersist,postPersist,preUpdate ......等事件相同。对于EntityManager.persis,update,查询具有不同的执行路径。实体经理在身份的基础上工作,因此它可以保证实体实际上已经更新。使用查询时无法告知相同内容。通常,实体管理器将执行一个查询以获取实体,而不是分析更改,然后UPDATE将发生,或者在没有更改的情况下不会发生。没有机制可以判断执行查询时是否确实发生了更新。
根据文档@Modifying注释并不能保证实际发生修改。保证的是会话将在方法调用后被清除。这背后的原因是,查询具有与正常持久化,合并方法不同的执行路由,并且您无法保证会话将保持完整性。因此@Modifying将保证它已被清除。