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

使用HSQLDB与Hibernate构建REST搜索接口时HQL抛出QueryException

解决Hibernate QueryException:无法解析Course.description的问题

我来帮你梳理下这个问题的原因和解决办法:

错误根源

你遇到的异常是因为HQL的语法用错啦。HQL是面向实体对象的查询语言,和原生SQL的规则不一样——当你在FROM后面指定了实体类Course之后,Hibernate已经明确知道你要操作的是这个实体,直接用属性名description就可以,不需要再加上实体类名Course.作为前缀,这就是为什么会抛出unexpected token [Course]的异常。

正确的HQL写法

有两种常用的正确写法:

  1. 直接使用属性名(适合简单查询场景)
FROM Course WHERE description LIKE '%a%' OR description LIKE '%e%'
  1. 使用实体别名(更推荐,复杂查询时可读性更高)
FROM Course c WHERE c.description LIKE '%a%' OR c.description LIKE '%e%'

结合REST API的实现示例

针对你的场景,需要把请求参数token分割成多个关键词,动态构建OR条件,这里给你两种安全可靠的实现方式:

方式1:动态拼接带参数绑定的HQL

一定要用参数绑定,绝对不能直接把用户输入的关键词拼进HQL字符串,否则会有SQL注入风险:

@GetMapping("/search")
public List<Course> searchCourses(@RequestParam String token) {
    // 按空格分割token为关键词数组
    String[] keywords = token.split("\\s+");
    
    StringBuilder hqlBuilder = new StringBuilder("FROM Course c WHERE ");
    // 拼接OR条件的参数占位符
    for (int i = 0; i < keywords.length; i++) {
        if (i > 0) {
            hqlBuilder.append(" OR ");
        }
        hqlBuilder.append("c.description LIKE :keyword").append(i);
    }
    
    // 创建查询并绑定参数
    Query query = session.createQuery(hqlBuilder.toString());
    for (int i = 0; i < keywords.length; i++) {
        query.setParameter("keyword" + i, "%" + keywords[i] + "%");
    }
    
    return query.list();
}

方式2:使用JPA Criteria Query(更优雅安全)

用Criteria API可以完全避免手动拼接字符串,可读性和安全性都更优:

@Autowired
private EntityManager entityManager;

@GetMapping("/search")
public List<Course> searchCourses(@RequestParam String token) {
    String[] keywords = token.split("\\s+");
    
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Course> query = cb.createQuery(Course.class);
    Root<Course> courseRoot = query.from(Course.class);
    
    // 构建每个关键词的LIKE查询条件
    List<Predicate> predicates = new ArrayList<>();
    for (String keyword : keywords) {
        predicates.add(cb.like(courseRoot.get("description"), "%" + keyword + "%"));
    }
    
    // 将所有条件用OR逻辑连接
    query.where(cb.or(predicates.toArray(new Predicate[0])));
    
    return entityManager.createQuery(query).getResultList();
}

额外注意点

  • 确认你的Course实体类中,description属性和数据库字段的映射是正确的(如果字段名和属性名不一致,要通过@Column注解指定)
  • 始终坚持用参数绑定处理用户输入,杜绝SQL注入风险
  • HSQLDB支持%作为LIKE查询的通配符,你的使用方式是符合要求的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:08:23