@EntityGraph注解不生效,Repository中default方法调用findAll未触发关联抓取?
问题原因
你当前的写法不生效是因为Spring Data JPA的@EntityGraph注解只会对框架自动实现的抽象查询方法生效,加在default默认方法上时,注解不会被查询代理识别解析,自然不会生效。你在default方法内部调用的是父类JpaRepository的原生findAll(),用的是默认的加载策略,和你加在default方法上的注解没有关联。
修复方案
方案1:声明抽象查询方法(最推荐,适配你的需求)
直接删除default实现,将需要关联抓取的方法声明为抽象方法,Spring Data JPA会自动实现该方法并应用你的@EntityGraph配置。如果需要两套查询逻辑,给第二个查询方法换个符合Spring Data命名规则的名称即可,比如:
public interface BspCategoryRepository extends JpaRepository<DbpMetaBspCategory, String> { // 带自定义EntityGraph的全表查询 @EntityGraph(attributePaths = {"dbpBBCollection","dbpBBCollection.dbpBBMetaCustomFieldCollection","dbpBBCollection.bspType","dbpBBCollection.bankCode","dbpBBCollection.dbpBBMetaCustomFieldCollection.fieldType"}, type = EntityGraph.EntityGraphType.FETCH) List<DbpMetaBspCategory> findAll(); // 不带关联抓取的默认全表查询,findAllBy会被Spring Data识别为全表查询逻辑 List<DbpMetaBspCategory> findAllBy(); }
方案2:用@Query写FETCH JOIN
如果需要更灵活控制关联抓取逻辑,也可以直接写JPQL的FETCH JOIN实现,可读性更高:
@Query("SELECT DISTINCT c FROM DbpMetaBspCategory c " + "LEFT JOIN FETCH c.dbpBBCollection b " + "LEFT JOIN FETCH b.dbpBMetaCustomFieldCollection f " + "LEFT JOIN FETCH f.fieldType " + "LEFT JOIN FETCH b.bspType " + "LEFT JOIN FETCH b.bankCode") List<DbpMetaBspCategory> findAllWithAssociations();
注意加DISTINCT是为了避免多集合关联查询产生的笛卡尔积重复数据,如果关联集合数量多建议改用分批查询避免性能问题。
方案3:编程式动态指定EntityGraph
如果需要运行时动态切换EntityGraph配置,可以直接用JPA原生的EntityGraph API实现:
@Service public class BspCategoryService { @Autowired private BspCategoryRepository categoryRepository; @Autowired private EntityManager entityManager; public List<DbpMetaBspCategory> findAllWithCustomGraph() { EntityGraph<DbpMetaBspCategory> graph = entityManager.createEntityGraph(DbpMetaBspCategory.class); graph.addAttributePaths("dbpBBCollection", "dbpBCollection.bspType"); return entityManager.createQuery("SELECT c FROM DbpMetaBspCategory c", DbpMetaBspCategory.class) .setHint("javax.persistence.fetchgraph", graph) .getResultList(); } }
内容的提问来源于stack exchange,提问作者Hasindu Dahanayake
相关产品推荐
相关产品推荐

