根据Spring Data JPA文档实现无@Query的泛型findAll投影方法遇问题
解决Spring Data JPA泛型findAll动态投影的方法命名问题
哥们,你遇到的这个报错其实是Spring Data JPA方法命名解析机制的小坑——你写的<T> List<T> findAll(Class<T> type)会被框架误解:它会把findAll和后面的参数结合,试图去匹配你实体类里的某个名为findAll的属性,而你的实体显然没有这个属性,所以才抛出了PropertyReferenceException。
不用@Query注解也能实现泛型的动态投影findAll方法,给你两个靠谱的方案:
方案一:换个不会被误解析的方法名
把方法名改成框架不会当成属性查询的名字,比如findAllAs或者findAllProjections,这样Spring Data JPA就会正确识别Class<T>参数是动态投影的目标类型:
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> { <T> List<T> findAllAs(Class<T> projectionType); }
调用的时候直接传投影类的Class对象就行:
List<YourProjection> projections = yourEntityRepository.findAllAs(YourProjection.class);
方案二:结合QueryByExample保留findAll方法名
如果你一定要用findAll作为方法名,可以结合Spring Data JPA的QueryByExample特性,传递一个空的Example对象,这样框架就不会把参数当成属性查询条件,而是识别为投影类型:
public interface YourEntityRepository extends JpaRepository<YourEntity, Long>, QueryByExampleExecutor<YourEntity> { <T> List<T> findAll(Example<YourEntity> example, Class<T> projectionType); }
调用的时候用空Example来触发查询:
List<YourProjection> projections = yourEntityRepository.findAll(Example.of(new YourEntity()), YourProjection.class);
注意事项
不管用哪个方案,你的投影类(T)都要符合Spring Data JPA的投影规则:
- 如果是接口,接口里的方法名要和实体类的getter方法对应(比如实体有
getName(),投影接口就可以定义String getName()); - 如果是普通类,需要有和实体属性名匹配的全参构造器。
内容的提问来源于stack exchange,提问作者pustypawel
相关产品推荐
相关产品推荐

