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

如何扩展PostgreSQL方言解决Hibernate SQL类型1111映射异常?

问题:Spring Boot集成测试中Hibernate MappingException(SQL类型1111无映射)

应用启动正常,但运行Testcontainers PostgreSQL容器的集成测试时,抛出org.hibernate.MappingException异常,提示:

无法确定some_table表id列的SQL类型名称,因为org.hibernate.type.SqlTypes代码1111(OTHER)无类型映射。

实体ID映射代码

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@Access(AccessType.PROPERTY)
@Type(value = SomeUUIDType.class, parameters = @Parameter(name = "column", value = "id"))
private UUID id;

自定义UUID类型代码(继承Hypersistence MutableType)

import io.hypersistence.utils.hibernate.type.MutableType;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.IndexedConsumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.type.descriptor.java.UUIDJavaType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.ParameterizedType;

import java.util.Properties;
import java.util.UUID;

public class SomeUUIDType extends MutableType<UUID, UUIDJdbcType, UUIDJavaType> implements ParameterizedType, EnhancedUserType<UUID> {

    public SomeUUIDType() {
        super(UUID.class, UUIDJdbcType.INSTANCE, UUIDJavaType.INSTANCE);
    }

    @Override
    public UUID fromStringValue(CharSequence seq) throws HibernateException {
        return UUID.fromString(seq.toString());
    }

    @Override
    public <X, Y> int forEachDisassembledJdbcValue(
            Object value,
            int offset,
            X x,
            Y y,
            JdbcValuesBiConsumer<X, Y> consumer,
            SharedSessionContractImplementor session
    ) {
        return 0;
    }

    @Override
    public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> indexedConsumer) {
        return 0;
    }

    @Override
    public void setParameterValues(Properties params) {
    }

    @Override
    public String toSqlLiteral(UUID value) {
        return value.toString();
    }

    @Override
    public String toString(UUID value) throws HibernateException {
        return value.toString();
    }
}

测试环境说明:使用Testcontainers PostgreSQL容器,配置文件和依赖已就绪,无法修改现有业务代码,需通过自定义PostgreSQL方言解决问题。


解决方案:自定义PostgreSQL方言

1. 编写自定义方言类

继承PostgreSQLDialect,重写类型注册逻辑,将SqlTypes.OTHER(代码1111)映射到PostgreSQL的uuid类型,并关联自定义SomeUUIDType:

import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.type.SqlTypes;

public class CustomPostgreSQLDialect extends PostgreSQLDialect {

    public CustomPostgreSQLDialect() {
        super();
        // 注册SqlTypes.OTHER对应PostgreSQL的uuid列类型
        registerColumnType(SqlTypes.OTHER, "uuid");
        // 将该JDBC类型关联到自定义的UUID类型
        registerHibernateType(SqlTypes.OTHER, SomeUUIDType.class.getName());
    }
}

2. 在测试配置中指定自定义方言

在测试专用的配置文件中,设置Hibernate方言为自定义类:

application-test.properties

spring.jpa.properties.hibernate.dialect=com.yourpackage.CustomPostgreSQLDialect

application-test.yml

spring:
  jpa:
    properties:
      hibernate:
        dialect: com.yourpackage.CustomPostgreSQLDialect

3. 核心原理

异常根源是Hibernate无法识别自定义类型默认映射的SqlTypes.OTHER,不知道对应数据库的具体列类型。通过自定义方言,我们显式声明:

  • SqlTypes.OTHER对应PostgreSQL的uuid列类型
  • 该JDBC类型使用SomeUUIDType处理转换逻辑

这样Hibernate在生成Schema、执行查询时就能正确匹配UUID列类型,避免MappingException。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:48:23