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

Hibernate升级至6.6.0.CR1+后原生查询JSON转义异常求助

Hibernate 6.6.0.CR1+ 原生查询美元引号包裹JSON的双引号转义问题及解决办法

问题概述

在hibernate-core版本≤6.6.0.Alpha1时,通过EntityManager.createNativeQuery执行带美元引号($dollar$)的原生插入查询可以正常运行,原SQL如下:

INSERT INTO example_table (geom) 
VALUES (
    ST_SetSRID(
        ST_GeomFromGeoJSON(
            $dollar${"type":"Point","coordinates":[-34.4214,-15.9216]}$dollar$
        ),
        4326
    )
) 
ON CONFLICT DO NOTHING;

此时Hibernate生成的执行语句与原查询完全一致。但升级到hibernate-core 6.6.0.CR1及以上版本(包括Spring Boot 3.4.x配套的Hibernate版本)后,Hibernate会错误地将JSON部分的双引号转义为多组双引号,生成的SQL变成:

INSERT INTO example_table (geom) 
VALUES (
    ST_SetSRID(
        ST_GeomFromGeoJSON(
            $dollar$""""""{type:Point,coordinates:[-34.4214,-15.9216]}$dollar$
        ),
        4326
    )
) 
ON CONFLICT DO NOTHING;;

这会直接触发PostgreSQL的「ERROR: unknown GeoJSON type」异常,且所有用美元引号包裹的JSON数据都会受此影响。当前仅能通过替换美元引号为单引号规避,但这并非预期方案。

问题原因

这是Hibernate 6.6.0版本开始的原生查询字符串解析逻辑变更导致的bug:新版本的解析器误将美元引号包裹的内容识别为普通字符串字面量,对其中的双引号执行了不必要的转义操作,破坏了GeoJSON的合法格式。

解决办法

方案1:绕过Hibernate的SQL解析,直接执行JDBC语句

通过unwrap获取底层JDBC对象,跳过Hibernate的字符串解析逻辑,直接执行原生SQL:

String nativeSql = "INSERT INTO example_table (geom) VALUES (ST_SetSRID(ST_GeomFromGeoJSON($dollar${\"type\":\"Point\",\"coordinates\":[-34.4214,-15.9216]}$dollar$), 4326)) ON CONFLICT DO NOTHING;";
EntityManager em = ...; // 获取EntityManager实例
em.unwrap(org.hibernate.Session.class)
   .createNativeQuery(nativeSql)
   .unwrap(java.sql.PreparedStatement.class)
   .executeUpdate();

方案2:使用参数化查询传递JSON内容

将JSON作为参数传入SQL,避免Hibernate解析SQL中的JSON字符串,同时符合安全的参数化查询规范:

String geoJson = "{\"type\":\"Point\",\"coordinates\":[-34.4214,-15.9216]}";
String nativeSql = "INSERT INTO example_table (geom) VALUES (ST_SetSRID(ST_GeomFromGeoJSON(?::jsonb), 4326)) ON CONFLICT DO NOTHING;";
EntityManager em = ...;
em.createNativeQuery(nativeSql)
   .setParameter(1, geoJson)
   .executeUpdate();

这种方式不仅能解决转义问题,还能避免SQL注入风险,是更推荐的实践方案。

方案3:临时回退Hibernate版本(不推荐)

如果暂时无法调整代码,可以临时回退到hibernate-core 6.6.0.Alpha1版本,但这会错过新版本的功能和安全修复,仅作为临时应急方案。

方案4:提交Bug报告推动官方修复

该问题属于Hibernate的解析逻辑bug,可以在Hibernate官方Issue平台提交复现步骤和版本信息,等待官方发布修复版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:59:50