Spring Boot 3(Hibernate 6)升级后PostgreSQL SQL语法错误求助
Spring Boot 3(Hibernate 6)升级后PostgreSQL LIKE语句转义符语法错误解决方案
问题描述
升级至Spring Boot 3(对应Hibernate 6)后,Hibernate生成的SQL中LIKE语句的转义符\未被正确处理,PostgreSQL抛出语法错误:
ERROR: syntax error at or near """
该查询在Spring Boot 2.7(Hibernate 5)中可正常执行,手动配置数据库方言无效,仅这类LIKE查询出错,带Specification的findAll等其他查询工作正常。
解决方案
1. 显式指定非默认转义符
在JPQL或Criteria查询中,显式指定转义符为非\的字符(比如#),避免与PostgreSQL的默认转义规则冲突:
- JPQL查询示例:
@Query("SELECT e FROM YourEntity e WHERE e.targetField LIKE :pattern ESCAPE '#'") List<YourEntity> findByTargetFieldLike(@Param("pattern") String pattern);
调用时需手动转义特殊字符(包括转义符自身):
// 原始查询串,包含\、%、_等特殊字符 String rawPattern = "test\\example_%"; // 转义处理:先转义转义符#,再转义LIKE通配符%和_ String escapedPattern = rawPattern.replace("#", "##") .replace("%", "#%") .replace("_", "#_"); List<YourEntity> result = yourRepository.findByTargetFieldLike("%" + escapedPattern + "%");
- Criteria API示例:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<YourEntity> query = cb.createQuery(YourEntity.class); Root<YourEntity> root = query.from(YourEntity.class); String pattern = "%test\\example_%"; // 显式指定转义符为# Expression<String> likeExpr = cb.like(root.get("targetField"), pattern, '#'); query.where(likeExpr); List<YourEntity> result = entityManager.createQuery(query).getResultList();
2. 配置Hibernate全局转义符
通过配置强制Hibernate使用指定的转义符,无需在每个查询中显式声明:
在application.properties或application.yml中添加:
# 指定PostgreSQL方言(Hibernate 6中确保使用正确的类路径) spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect # 全局设置LIKE语句的转义符 spring.jpa.properties.hibernate.query.like_escape_char=#
配置后,Hibernate生成LIKE语句时会自动使用#作为转义符,无需手动处理转义逻辑。
3. 改用原生SQL查询
如果前两种方案无效,直接使用原生SQL绕过Hibernate的转义处理:
@Query(value = "SELECT * FROM your_entity_table WHERE target_field LIKE ?1 ESCAPE '#'", nativeQuery = true) List<YourEntity> findByTargetFieldLikeNative(String pattern);
调用时同样需要手动转义特殊字符,逻辑同JPQL示例。
问题原因
Hibernate 6对LIKE语句的转义逻辑做了调整:
- Hibernate 5会自动将
\转义为\\,适配PostgreSQL的转义规则; - Hibernate 6默认生成的
ESCAPE '\'在PostgreSQL中会触发语法错误——因为PostgreSQL中\本身是字符串转义符,需要写成ESCAPE '\\',或使用其他非默认转义字符。
手动配置方言无效可能是因为方言配置未正确生效,或是Hibernate 6的方言默认转义策略与旧版本不一致。
内容的提问来源于stack exchange,提问作者HJED
相关产品推荐
相关产品推荐

