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

Spring Boot 2.7+Hibernate Envers插入审计版本时IDENTITY函数未找到

问题:Hibernate Envers插入审计版本时触发call identity()报错

插入审计版本时出现如下错误日志:

Hibernate: insert into audited_revision (id, timestamp) values (default, ?)
2022-07-21 15:46:09.496 TRACE 67111 --- [  XNIO-1 task-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [Thu Jul 21 15:46:09 CEST 2022]
Hibernate: call identity()
2022-07-21 15:46:09.504  WARN 67111 --- [  XNIO-1 task-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 90022, SQLState: 90022
2022-07-21 15:46:09.504 ERROR 67111 --- [  XNIO-1 task-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Function "IDENTITY" not found; SQL statement:
call identity() [90022-214]
2022-07-21 15:46:09.518 ERROR 67111 --- [  XNIO-1 task-1] o.z.problem.spring.common.AdviceTraits   : Internal Server Error

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [call identity()]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement

日志显示审计表已正确创建:

Hibernate: create table audited_revision (id bigint generated by default as identity, timestamp timestamp, primary key (id))

当前使用Spring Boot 2.7.2(对应Hibernate Core 5.6.9),相关application.yaml配置:

spring:
  jpa:
    defer-datasource-initialization: true
    database: H2
    hibernate:
      ddl-auto: create-drop
    open-in-view: false
    properties:
      format_sql: true
      org:
        hibernate:
          envers:
            store_data_at_delete: true
      hibernate:
        temp:
          use_jdbc_metadata_defaults: false
        dialect: org.hibernate.dialect.H2Dialect
    show-sql: true

已知Hibernate相关问题在5.6.5版本已修复,但当前版本仍触发该错误,询问是Bug还是配置问题。


原因分析与解决方案

这大概率是配置问题,而非Hibernate的Bug,核心问题出在hibernate.temp.use_jdbc_metadata_defaults=false这个配置上:

  • 当设置该参数为false时,Hibernate会跳过从JDBC元数据中获取数据库特性的步骤,转而完全依赖配置的方言类提供数据库语法规则。
  • 但org.hibernate.dialect.H2Dialect在处理自增主键返回逻辑时,需要结合JDBC元数据判断H2的具体版本特性,关闭元数据读取后,Hibernate无法正确识别H2支持的主键返回语法,错误生成了过时的call identity()语句(H2实际支持直接调用IDENTITY()函数,而非call语法)。

修复步骤

  1. 优先方案:移除hibernate.temp.use_jdbc_metadata_defaults=false配置(默认值为true),让Hibernate通过JDBC元数据自动适配H2的语法特性。
  2. 备选方案:如果必须关闭元数据读取,需指定与当前H2版本匹配的专用方言,比如org.hibernate.dialect.H212107Dialect(根据你的H2版本选择对应子类),确保方言能正确输出H2兼容的主键返回语句。

同时确认H2数据库版本与Hibernate方言版本匹配,避免因版本不兼容导致的语法差异。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:27:07