Spring Data JPA实现过滤分页时List转Page类型不匹配报错求解
问题原因
报错由两处代码逻辑错误共同导致:
- Repository层自定义查询方法接收
Pageable参数,但返回值定义为List<Utente>,Spring Data JPA不会为List返回值封装分页元数据(总条数、总页数、当前页位置等分页信息),仅会返回当前分页区间内的实体列表。 - Service层最终通过
Collectors.toList()将映射后的Dto收集为List<UtenteDto>,但方法签名要求返回Page<UtenteDto>,直接触发类型不匹配的编译错误。
修复方案
1. 调整Repository层方法返回值
将自定义查询方法的返回值从List<Utente>改为Page<Utente>,Spring Data JPA会自动触发分页查询、生成对应的count语句,返回携带完整分页信息的分页对象:
String FILTER_UTENTE_NOME_AND_COGNOME_QUERY = "select b from Utente b where UPPER(b.nome) like CONCAT('%',UPPER(?1),'%') and UPPER(b.cognome) like CONCAT('%',UPPER(?2),'%')"; @Query(FILTER_UTENTE_NOME_AND_COGNOME_QUERY) Page<Utente> findByFirstNameLikeAndLastNameLike(String nomeFilter, String cognomeFilter,Pageable pageable);
若后续使用多表关联的复杂查询,JPA无法自动推导count语句时,可在
@Query注解中补充countQuery参数手动指定count查询语句,当前单表查询无需额外配置。
2. 调整Service层转换逻辑
直接使用Page接口自带的map()方法完成实体到Dto的转换,该方法会自动保留所有分页元数据,无需手动转Stream收集为List:
public Page<UtenteDto> findByFirstNameLikeAndLastNameLike(String nomeFilter, String cognomeFilter, int page, int size){ Pageable pageable= PageRequest.of(page, size); return utenteRepository.findByFirstNameLikeAndLastNameLike(nomeFilter,cognomeFilter,pageable) .map(e -> mapper.map(e,UtenteDto.class)); }
3. 清理Controller层无效代码
Controller中声明的AccessTokenAccountRepository repository;是未被使用的冗余代码,直接删除即可,其余逻辑无需调整,修正后代码如下:
@GetMapping("/utenti") @ResponseStatus(value = HttpStatus.OK) public Page<UtenteDto> getAllFilteredByNomeAndCognome(@RequestParam(defaultValue = "") String nomeFilter, @RequestParam(defaultValue = "") String cognomeFilter, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "30") int size){ return utenteService.findByFirstNameLikeAndLastNameLike(nomeFilter,cognomeFilter,page,size); }
内容的提问来源于stack exchange,提问作者Java
相关产品推荐
相关产品推荐

