使用HSQLDB与Hibernate构建REST搜索接口时HQL抛出QueryException
解决Hibernate QueryException:无法解析Course.description的问题
我来帮你梳理下这个问题的原因和解决办法:
错误根源
你遇到的异常是因为HQL的语法用错啦。HQL是面向实体对象的查询语言,和原生SQL的规则不一样——当你在FROM后面指定了实体类Course之后,Hibernate已经明确知道你要操作的是这个实体,直接用属性名description就可以,不需要再加上实体类名Course.作为前缀,这就是为什么会抛出unexpected token [Course]的异常。
正确的HQL写法
有两种常用的正确写法:
- 直接使用属性名(适合简单查询场景)
FROM Course WHERE description LIKE '%a%' OR description LIKE '%e%'
- 使用实体别名(更推荐,复杂查询时可读性更高)
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
相关产品推荐
相关产品推荐

