Spring Data Envers如何实现修订实体的延迟加载?
解决Spring Data Envers批量加载实体的问题
针对你遇到的RevisionRepository立即加载所有实体的问题,有几个实用方法可以实现先获取修订元数据、按需加载实体的需求:
自定义原生查询获取修订号和时间戳
直接操作Envers生成的REVINFO表和实体对应的_aud表,只查询需要的字段,完全避开实体加载:@Query(value = "SELECT r.rev, r.revtstmp FROM REVINFO r " + "JOIN YourEntity_aud a ON r.rev = a.rev " + "WHERE a.id = :entityId " + "ORDER BY r.rev DESC", nativeQuery = true) List<Object[]> getRevisionMetadata(Long entityId);返回的列表里每个数组第一个元素是
rev_id,第二个是时间戳,不会实例化任何实体对象。用AuditReader按需加载特定修订实体
当需要查看某条修订的详情时,通过Hibernate的AuditReader手动查询,只加载对应版本的实体:@Autowired private EntityManager entityManager; public YourEntity getEntityRevision(Long entityId, Integer revId) { AuditReader auditReader = AuditReaderFactory.get(entityManager); return auditReader.find(YourEntity.class, entityId, revId); }这种方式只会在你主动调用时才去数据库拉取对应修订的实体数据,避免一次性加载几百个实例。
Spring Data投影接口简化元数据查询
定义一个投影接口来指定要获取的字段,不用写原生SQL也能只拿修订元数据:public interface RevisionMeta { Integer getRev(); Long getRevtstmp(); } // 在你的Repository中添加方法 @Query("SELECT r.rev as rev, r.revtstmp as revtstmp FROM RevisionEntity r " + "JOIN r.revisions a WHERE a.entity.id = :entityId") List<RevisionMeta> findRevisionMetaByEntityId(Long entityId);Spring Data会自动把查询结果映射到投影接口,只返回你需要的两个字段。
不推荐:修改Envers加载策略
虽然可以尝试给实体的@Audited配置懒加载,但Envers默认的立即加载是有设计考量的,改懒加载容易引发N+1查询问题,不如前面几种方法可控,所以优先选前面的方案。
内容的提问来源于stack exchange,提问作者peterh
相关产品推荐
相关产品推荐

