为什么JpaRepository(Spring Data JPA)自定义查询总是返回空列表?
问题原因
- 原生SQL中命名占位符
:main被写在单引号内部,Spring Data JPA不会识别单引号中的命名参数,实际执行时不会将:main替换为传入的搜索词,而是直接以字符串%:main%去匹配数据库内容,自然无法返回符合条件的结果。 - 若
AnnuncioEntity实体的字段映射配置有误,或者没有和SQL返回的字段一一对应,也会导致查询结果无法正常封装为实体,最终返回空列表。
修复方案
方案1:SQL层用CONCAT拼接通配符
调整Repository层的@Query注解写法,将通配符和参数用数据库函数拼接,保证占位符可以被正常识别:
@Query(value = "select distinct a.ann_id, a.nome, a.autore, a.descrizione, a.prodotto, a.prezzo " + "from annunci a, prodotti p " + "where a.prodotto = p.prod_id " + "and (a.nome like CONCAT('%', :main, '%') or p.nome like CONCAT('%', :main, '%'))", nativeQuery = true) public List<AnnuncioEntity> searchWithoutFilters(String main);
方案2:业务层拼接通配符
也可以在调用DAO方法前提前给搜索词拼接好通配符,SQL层直接使用占位符即可:
Repository层代码:
@Query(value = "select distinct a.ann_id, a.nome, a.autore, a.descrizione, a.prodotto, a.prezzo " + "from annunci a, prodotti p " + "where a.prodotto = p.prod_id " + "and (a.nome like :main or p.nome like :main)", nativeQuery = true) public List<AnnuncioEntity> searchWithoutFilters(String main);
Controller层调用代码调整:
@PostMapping("/") public List<FullAnnuncio> searchAnnunci(@RequestBody SearchEntity search) { // 提前拼接通配符 String searchParam = "%" + search.getMain() + "%"; List<AnnuncioEntity> li = annuncioDAO.searchWithoutFilters(searchParam); // 后续实体转换逻辑自行补充 return null; }
额外校验点
- 确认
AnnuncioEntity的字段名和SQL查询返回的字段名完全匹配,或配置了正确的@Column映射注解,保证查询结果可以正常封装为实体。 - 可在配置文件中开启SQL打印,确认实际执行的SQL和参数是否符合预期:
# application.properties新增配置 spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
内容的提问来源于stack exchange,提问作者santocielo99
相关产品推荐
相关产品推荐

