如何扩展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
相关产品推荐
相关产品推荐

