Spring Data从2.0迁3.0:PagingAndSortingRepository使用问题求助
解决方案与知识点解析
核心问题原因
Spring Data 3.0(对应Spring Boot 3)对Repository体系做了职责拆分:原版本中PagingAndSortingRepository继承CrudRepository,但新版本里二者完全解耦——PagingAndSortingRepository仅负责分页/排序能力,不再包含CRUD方法,所以你的基类里的repository变量自然找不到findById方法。
正确的泛型修改方式
你需要给泛型R添加多重接口约束,让它同时继承PagingAndSortingRepository和CRUD相关的Repository接口,Java支持接口的多继承约束,用&符号连接即可。
方式一:兼容原有CRUD方法(返回Optional)
修改基类的泛型声明,让R同时实现PagingAndSortingRepository和CrudRepository:
public abstract class AbstractBaseServiceImpl<R extends PagingAndSortingRepository<E, K> & CrudRepository<E, K>, E extends AbstractBaseEntity, K extends Serializable, M> implements AbstractBaseService<E, K, M> { protected Logger logger = LoggerFactory.getLogger(getClass()); protected R repository; // 此时调用repository.findById(id)完全正常 public E getEntityById(K id) { return repository.findById(id).orElse(null); } }
方式二:使用Spring Data 3.0新API(返回List)
如果想适配新版本的API,推荐用ListCrudRepository(它的CRUD方法返回List而非Iterable,更符合日常开发习惯),泛型约束调整为:
public abstract class AbstractBaseServiceImpl<R extends PagingAndSortingRepository<E, K> & ListCrudRepository<E, K>, E extends AbstractBaseEntity, K extends Serializable, M> implements AbstractBaseService<E, K, M> { // ... 其余代码不变 }
为什么你之前的写法错误?
你之前把CrudRepository<E, K>当成了第二个泛型参数,这是对泛型语法的误解:泛型参数是类型变量(比如R、E),而不是直接写具体的接口类。我们要做的是给同一个类型变量R添加多个接口实现约束,而非新增一个泛型参数。
补充知识点:Spring Data 3.0 Repository体系拆分
新版本把原有的大而全的Repository拆分为职责单一的接口:
PagingAndSortingRepository:仅提供分页、排序方法(findAll(Pageable)、findAll(Sort))CrudRepository:提供基于Optional的CRUD方法(比如findById返回Optional<E>)ListCrudRepository:提供返回List的CRUD方法(比如findAll返回List<E>)ListPagingAndSortingRepository:整合ListCrudRepository和PagingAndSortingRepository的能力(JpaRepository默认继承这个接口)
你的业务Repository(比如基于JPA的实现)本来就同时实现了这些接口,所以泛型约束的修改不会影响现有实现类的兼容性。
内容的提问来源于stack exchange,提问作者Onni
相关产品推荐
相关产品推荐

