You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate执行HQL查询报错QuerySyntaxException:ILIKE语法问题

问题分析

HQL是Hibernate为跨数据库兼容设计的查询语言,并不原生支持PostgreSQL特有的ILIKE和ANY(ARRAY[])语法——这就是你触发QuerySyntaxException的核心原因。而Adminer直接执行的是原生PostgreSQL SQL,所以能正常运行。

解决方案

根据你的场景需求,可以选择以下几种处理方式:

1. 直接使用原生SQL查询

这是最直接的方案,绕过HQL的语法限制,直接执行PostgreSQL原生语句:

String sql = "SELECT * FROM your_table WHERE your_column ILIKE ANY(ARRAY[:keywords])";
Query query = entityManager.createNativeQuery(sql, YourEntity.class);
query.setParameter("keywords", new String[]{"%foo%", "%bar%"});
List<YourEntity> results = query.getResultList();

2. 用HQL模拟ILIKE效果(跨数据库友好)

如果需要保留HQL的跨数据库特性,可以通过upper()函数把字段和参数统一转成大写,再用普通like实现不区分大小写匹配:

List<String> keywords = Arrays.asList("%FOO%", "%BAR%");
String hql = "FROM YourEntity e WHERE upper(e.yourColumn) IN (:keywords)";
Query query = session.createQuery(hql, YourEntity.class);
query.setParameter("keywords", keywords.stream().map(String::toUpperCase).collect(Collectors.toList()));
List<YourEntity> results = query.getResultList();

注意:如果关键词带通配符,IN无法实现模糊匹配,此时需要用OR连接多个like条件,或者参考下面的自定义函数方案。

3. 自定义HQL函数支持ILIKE ANY

通过扩展Hibernate的函数注册,让HQL直接支持PostgreSQL的ILIKE ANY语法:

  • 首先在Spring Boot配置文件中指定自定义方言函数注册器:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.query.registrar.postgresql=your.package.CustomPostgreSQLFunctionRegistrar
  • 实现函数注册器:
public class CustomPostgreSQLFunctionRegistrar implements FunctionContributor {
    @Override
    public void contributeFunctions(FunctionContributions functionContributions) {
        functionContributions.getFunctionRegistry().register(
            "ilike_any",
            new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN, "?1 ILIKE ANY(?2)")
        );
    }
}
  • 之后即可在HQL中使用自定义函数:
String hql = "FROM YourEntity e WHERE ilike_any(e.yourColumn, :keywords)";
Query query = session.createQuery(hql, YourEntity.class);
query.setParameter("keywords", new String[]{"%foo%", "%bar%"});
List<YourEntity> results = query.getResultList();

4. 用Criteria API构建查询

如果偏好类型安全的查询方式,用Criteria API通过OR连接多个模糊匹配条件,模拟ILIKE ANY的效果:

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<YourEntity> cq = cb.createQuery(YourEntity.class);
Root<YourEntity> root = cq.from(YourEntity.class);

List<String> keywords = Arrays.asList("%foo%", "%bar%");
Predicate[] predicates = keywords.stream()
    .map(keyword -> cb.like(cb.upper(root.get("yourColumn")), keyword.toUpperCase()))
    .toArray(Predicate[]::new);

cq.where(cb.or(predicates));
List<YourEntity> results = session.createQuery(cq).getResultList();

内容的提问来源于stack exchange,提问作者yesIamFaded

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:45:46