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

Liquibase Maven插件集成liquibase-hibernate5时JSONB类加载报错咨询

问题背景
  • 运行环境:Liquibase core、liquibase-hibernate5 4.10,Spring Boot 2.5.14
  • 目标:适配PostgreSQL JSONB类型,执行mvn liquibase:diff时正常识别该类型
  • 已完成的配置:
    • 自定义继承PostgreSQL10Dialect的方言类,代码如下:
      public class PostgreSQLDialect extends PostgreSQL10Dialect {
      
          public PostgreSQLDialect() {
              // 注册JSONB列类型,避免liquibase插件执行失败
              System.out.println("Registering the JSONB type.");
              this.registerColumnType(Types.JAVA_OBJECT, "jsonb");
          }
      }
      
    • application.yml中指定Hibernate使用自定义方言:
      spring.jpa.properties.hibernate.dialect: my.example.PostgreSQLDialect
      
    • pom.xml中liquibase插件的referenceUrl配置指定自定义方言:
      <referenceUrl>hibernate:spring:my.example.persist?dialect=my.exampple.PostgreSQLDialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl</referenceUrl>
      
  • 故障现象:执行mvn liquibase:diff时,日志显示自定义方言已加载、JSONB类型注册完成,但抛出ClassNotFoundException: Could not load requested class : jsonb异常,此前只能通过注释JSONB相关代码临时规避。完整异常栈如下:
    Caused by: java.lang.ClassNotFoundException: Could not load requested class : jsonb
        at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass (AggregatedClassLoader.java:210)
        at java.lang.ClassLoader.loadClass (ClassLoader.java:589)
        at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
        at java.lang.Class.forName0 (Native Method)
        at java.lang.Class.forName (Class.java:427)
        at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName (ClassLoaderServiceImpl.java:130)
        at org.hibernate.boot.internal.ClassLoaderAccessImpl.classForName (ClassLoaderAccessImpl.java:67)
        at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue (SimpleValueBinder.java:536)
        at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass (SetSimpleValueTypeSecondPass.java:25)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses (InFlightMetadataCollectorImpl.java:1693)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses (InFlightMetadataCollectorImpl.java:1651)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete (MetadataBuildingProcess.java:295)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata (EntityManagerFactoryBuilderImpl.java:1224)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build (EntityManagerFactoryBuilderImpl.java:1255)
        at liquibase.ext.hibernate.database.HibernateEjb3Database.buildMetadataFromPath (HibernateEjb3Database.java:59)
        at liquibase.ext.hibernate.database.HibernateDatabase.buildMetadata (HibernateDatabase.java:143)
        at liquibase.ext.hibernate.database.HibernateDatabase.setConnection (HibernateDatabase.java:83)
    .....
    
故障原因
  • 配置存在笔误:referenceUrl中配置的方言类路径为my.exampple.PostgreSQLDialect,多写了一个字母p,和实际类路径my.example.PostgreSQLDialect不匹配。
  • 方言配置不完整:仅通过registerColumnType注册JDBC类型到SQL列类型的映射,只能解决SQL生成阶段的类型识别问题。Hibernate解析实体类上的@Type(type = "jsonb")注解时,会将jsonb作为类名尝试加载,找不到对应的Hibernate Type实现就会抛出类不存在异常。
解决步骤
  1. 修正pom.xml中referenceUrl的方言类名笔误,将my.exampple.PostgreSQLDialect改为实际的全限定类名my.example.PostgreSQLDialect。
  2. 补全JSONB类型的Hibernate注册逻辑,可直接使用成熟的hibernate-types实现,也可自定义UserType:
    • 引入适配Hibernate 5.4+版本的hibernate-types依赖:
      <dependency>
          <groupId>com.vladmihalcea</groupId>
          <artifactId>hibernate-types-52</artifactId>
          <version>2.14.0</version>
      </dependency>
      
    • 修改自定义方言类,补充Hibernate类型注册:
      import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
      import org.hibernate.dialect.PostgreSQL10Dialect;
      import java.sql.Types;
      
      public class PostgreSQLDialect extends PostgreSQL10Dialect {
          public PostgreSQLDialect() {
              super();
              // 注册JDBC类型到JSONB列类型的映射
              this.registerColumnType(Types.JAVA_OBJECT, "jsonb");
              // 注册Hibernate类型,绑定jsonb标识到JsonBinaryType实现类
              this.registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
          }
      }
      
    • 在使用JSONB类型的实体类上添加类型定义,明确jsonb标识对应的实现类:
      import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
      import org.hibernate.annotations.Type;
      import org.hibernate.annotations.TypeDef;
      import javax.persistence.Column;
      import javax.persistence.Entity;
      
      @Entity
      @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
      public class YourEntity {
          // 其他实体字段
      
          @Type(type = "jsonb")
          @Column(columnDefinition = "jsonb")
          private YourJsonDto jsonConfigField;
      }
      
  3. 执行mvn clean liquibase:diff验证,异常即可消除。

注:如果不希望引入第三方依赖,可自行实现org.hibernate.usertype.UserType接口完成JSONB类型的序列化、反序列化逻辑,注册流程和上述一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:36:22