使用@Cacheable与JPA二级缓存时出现EntityNotFoundException异常咨询
问题根因
该异常本质是Hibernate二级缓存中集合缓存与关联实体缓存不一致导致的:
当你直接删除Reservation实体时,Hibernate只会清空Reservation自身的实体缓存,不会主动更新所有关联到它的Desk实体的reservations集合缓存。后续你加载对应Desk时,Hibernate会先读取集合缓存中存储的Reservation ID列表,再拿着这些ID去查询实体缓存或数据库,此时已删除的ID对应的实体不存在,就会抛出EntityNotFoundException。
解决方案
根据你的业务场景可以选择以下任意一种方案:
- 方案1:维护关联关系双向同步,删除关联实体时主动更新集合
删除Reservation时先获取关联的Desk,将待删除的Reservation从Desk的reservations集合中移除,Hibernate会自动触发集合缓存更新,保证一致性,代码示例:
@Transactional public void deleteReservation(Long reservationId) { Reservation reservation = reservationRepository.findById(reservationId) .orElseThrow(() -> new RuntimeException("Reservation not found")); // 主动更新关联集合,触发缓存同步 Desk desk = reservation.getDesk(); desk.getReservations().remove(reservation); reservationRepository.delete(reservation); }
- 方案2:删除关联实体后手动清除对应集合缓存
如果你不想修改业务逻辑的关联关系维护流程,可以在删除Reservation后主动清除对应Desk的集合缓存,代码示例:
@PersistenceContext private EntityManager entityManager; @Transactional public void deleteReservation(Long reservationId) { Reservation reservation = reservationRepository.findById(reservationId) .orElseThrow(() -> new RuntimeException("Reservation not found")); Long deskId = reservation.getDesk().getId(); reservationRepository.delete(reservation); // 手动清除指定Desk的reservations集合缓存 entityManager.getEntityManagerFactory().getCache() .evictCollection(Desk.class.getName() + ".reservations", deskId); }
- 方案3:调整集合缓存的并发策略
如果你的业务允许短时间的数据不一致、并发修改频率低,可以将集合的缓存策略改为@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE),该策略不会抛出找不到实体的异常,会自动回源查询数据库同步缓存。 - 方案4:关闭关联集合的二级缓存
如果关联实体删除操作非常频繁、对一致性要求极高,可以直接去掉集合上的@Cache注解,牺牲少量读性能避免缓存一致性问题。
调试方法
你可以通过以下步骤定位缓存不一致的具体环节:
- 开启Hibernate缓存日志和统计功能,确认缓存的命中、失效情况,Spring Boot配置示例如下:
spring: jpa: properties: hibernate: show_sql: true format_sql: true use_sql_comments: true generate_statistics: true cache: use_second_level_cache: true log: logger: org.hibernate.cache: TRACE org.hibernate.stat: DEBUG
- 复现问题时观察日志输出,确认删除
Reservation后,加载Desk时是否读取到了已删除的ReservationID。 - 测试手动清除集合缓存后异常是否消失,验证问题是否确实由缓存不一致导致。
内容的提问来源于stack exchange,提问作者Jose A. Matarán
相关产品推荐
相关产品推荐

