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

HQL中使用JSON_TRANSFORM更新JSON字段失败求助

解决方案

问题根源

HQL是Hibernate的跨数据库查询语言,它不支持Oracle专属的json_transform函数语法,所以直接写在HQL更新语句里会触发语法解析异常——哪怕这条语句在Oracle SQL Developer里能正常运行。

可行方案

1. 改用原生SQL执行更新操作

直接使用Hibernate的createNativeQuery方法执行Oracle原生SQL,绕过HQL的语法校验:

String updateSql = "update MY_DETAILS set details = json_transform(details, set '$.defaultValue' = :defaultValue0) where json_value(details, '$.defaultValue') = :defaultValue1";
Query query = entityManager.createNativeQuery(updateSql);
query.setParameter("defaultValue0", 0);
query.setParameter("defaultValue1", 1);
query.executeUpdate();

注意表名要写数据库里的实际表名(Oracle默认表名大写),而非实体类名。

2. 封装JSON更新逻辑到数据库存储过程

如果需要复用这个更新逻辑,可以在Oracle中创建存储过程,再通过Hibernate调用:

CREATE OR REPLACE PROCEDURE reset_default_value(p_new_default_val NUMBER, p_old_default_val NUMBER) AS
BEGIN
  UPDATE MY_DETAILS 
  SET details = json_transform(details, set '$.defaultValue' = p_new_default_val) 
  WHERE json_value(details, '$.defaultValue') = p_old_default_val;
END;
/

Java代码中调用存储过程:

StoredProcedureQuery spq = entityManager.createStoredProcedureQuery("reset_default_value");
spq.registerStoredProcedureParameter("p_new_default_val", Integer.class, ParameterMode.IN);
spq.registerStoredProcedureParameter("p_old_default_val", Integer.class, ParameterMode.IN);
spq.setParameter("p_new_default_val", 0);
spq.setParameter("p_old_default_val", 1);
spq.execute();

补充说明

  • 你的查询语句能用HQL执行,是因为json_value在部分Hibernate版本中被识别为兼容函数,但json_transform是Oracle 12cR2+的专属函数,HQL没有内置支持。
  • 执行更新时务必开启事务,避免并发场景下出现多条记录默认值为1的情况,可通过行级锁或事务隔离级别控制并发。

内容的提问来源于stack exchange,提问作者Rachan R K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:40:05