我正在尝试使用 JPARepository 和 Criteria API 执行查询,但似乎存储库中的方法只是忽略传递给它的规范。
这是我的存储库界面:
public interface MovieRepository extends JpaRepository<Movie, String>, JpaSpecificationExecutor<Movie> {}
我想使用的规格:
public static Specification<Movie> hasTitleLike(String title) {
return (root, query, criteriaBuilder) ->
criteriaBuilder.like(criteriaBuilder.lower(root.get("title")), title.toLowerCase());
}
我正在执行的 JpaRepository 查询:
movieRepository.findAll(MovieSpecifications.hasTitleLike(title), pageable);
存储库返回正确排序的页面,因此可分页参数有效,但它不会按规范以任何方式过滤。
我正在使用 spring-boot-starter-parent 和 spring-boot-starter-jpa 版本 3.1.5 和 openJDK 21。
我能够在本地运行一个非常相似的示例,并且 lower() 上的 MovieSpecification.hasTitleLike() 过滤器正在工作。
几个问题:
当您说过滤不起作用时,您是什么意思?您的意思是它不按标题过滤,基本上只是执行 Select * 吗?
您可以提供您正在使用的数据库供应商和版本吗?即 MySQL 8.2.0、H2 等...
你能提供完整的电影课程吗?
最后,为了帮助调试,如果使用以下 application.properties 设置打开 Hibernate 日志记录,您应该能够看到更多信息:
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.orm.jdbc.bind=TRACE
休眠日志:
select
m1_0.id,
m1_0.title
from
movie m1_0
where
lower(m1_0.title) like ? escape ''
order by
m1_0.id offset ? rows fetch first ? rows only
2023-10-26T12:47:49.585-07:00 TRACE 29220 --- [ main] org.hibernate.orm.jdbc.bind : binding parameter [1] as [VARCHAR] - [jurassic park]
2023-10-26T12:47:49.585-07:00 TRACE 29220 --- [ main] org.hibernate.orm.jdbc.bind : binding parameter [2] as [INTEGER] - [10]
2023-10-26T12:47:49.585-07:00 TRACE 29220 --- [ main] org.hibernate.orm.jdbc.bind : binding parameter [3] as [INTEGER] - [10]