使用@GetMapping多参数搜索产品时触发org.hibernate.query.SemanticException问题排查
异常信息(中文翻译)
org.hibernate.query.SemanticException: 查询发生异常 [SELECT p FROM Products p WHERE (:productId is null or p.productId = :productId) and (:p.productName is null or p.productName = :productName) and (:p.brandId is null or p.brandId = :brandId) and (:p.categoryId is null or p.categoryId = :categoryId) and (:p.modelYear is null or p.modelYear = :modelYear)]
错误原因
你在ProductRepository.java的@Query语句中错误引用了参数:除:productId外,其他参数(如:p.productName、:p.brandId)的写法违反HQL参数规则。HQL参数名必须与@Param注解定义的名称完全一致,不能添加实体别名p.,这种错误写法导致Hibernate无法识别参数,触发语义异常。
修正后的代码
ProductRepository.java
@Query("SELECT p FROM Products p WHERE (:productId is null or p.productId = :productId) and " + "(:productName is null or p.productName = :productName) and " + "(:brandId is null or p.brandId = :brandId) and " + "(:categoryId is null or p.categoryId = :categoryId) and " + "(:modelYear is null or p.modelYear = :modelYear)") List<Product> findProductBySearch(@Param("productId") Integer productId, @Param("productName") String productName, @Param("brandId") Integer brandId, @Param("categoryId") Integer categoryId, @Param("modelYear") Integer modelYear);
潜在优化建议
你的Product.java实体中,brandId、categoryId、modelYear字段为int基本类型,但接口参数是支持null的Integer类型。当参数传递null时会触发自动拆箱操作,可能引发NullPointerException。建议将这些字段改为Integer包装类型:
@Column(name = "brand_id") Integer brandId; @Column(name = "category_id") Integer categoryId; @Column(name = "model_year") Integer modelYear;
内容的提问来源于stack exchange,提问作者Minh Nguyễ Nguyễn Đức

