Hibernate支持Postgresql UUID?
我不能让Hibernate使用java.util.UUID for PostgreSQL。
这是使用javax.persistence的映射。* annotations:
private UUID itemUuid; @Column(name="item_uuid",columnDefinition="uuid NOT NULL") public UUID getItemUuid() { return itemUuid; } public void setItemUuid(UUID itemUuid) { this.itemUuid = itemUuid; }
当持久化对象时,我得到一个SQLGrammarException:
column "item_uuid" is of type uuid but expression is of type bytea at character 149
PostgreSQL版本是8.4.4
JDBC驱动程序 – 8.4.4-702(也试过9.0 – 同样的事情)
Hibernate版本是3.6,主要配置属性:
org.hibernate.dialect.PostgreSQLDialect org.postgresql.Driver jdbc:postgresql://192.168.1.1/db_test
这可以通过向UUID添加以下注释来解决:
import org.hibernate.annotations.Type; ... @Type(type="pg-uuid") private java.util.UUID itemUuid;
至于为什么Hibernate不只是将它设为默认设置,我无法告诉你……
更新:使用createNativeQuery方法打开具有UUID字段的对象似乎仍然存在问题。 幸运的是,到目前为止,createQuery方法对我来说很好。
您尝试持久化UUID类型的对象,这不是带有hibernate注释的实体。 所以hibernate想要将它序列化为字节数组(blob类型)。 这就是为什么你得到这个消息’类型为bytea’的表达式。
您可以将UUID作为blob存储在数据库中(不是优雅的),或者提供自定义序列化程序(很多工作)或手动转换该对象。 UUID类有fromString和toString方法,所以我将它存储为String。
正如其他人提到的,这个问题的解决方案是添加@Type(type = "pg-uuid")
注释。 但是,此类型与其他供应商的UUID类型不兼容,因此这将您的Hibernate类与Postgres联系起来。 要解决此问题,可以在运行时插入此批注。 以下适用于Hibernate 4.3.7。
首先,您需要插入自定义元数据提供程序以插入注释。 这是创建Configuration
类实例后的第一步:
// Perform some test to verify that the current database is Postgres. if (connectionString.startsWith("jdbc:postgresql:")) { // Replace the metadata provider with our custom metadata provider. MetadataProviderInjector reflectionManager = MetadataProviderInjector)cfg.getReflectionManager(); reflectionManager.setMetadataProvider(new UUIDTypeInsertingMetadataProvider(reflectionManager.getMetadataProvider())); }
此自定义元数据提供程序查找UUID
类型的字段和方法。 如果找到一个,它会插入一个org.hibernate.annotations.Type
注释的实例,声明该类型应为"pg-uuid"
:
package nl.gmt.data; import org.hibernate.annotations.Parameter; import org.hibernate.annotations.Type; import org.hibernate.annotations.common.reflection.AnnotationReader; import org.hibernate.annotations.common.reflection.MetadataProvider; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.UUID; class UUIDTypeInsertingMetadataProvider implements MetadataProvider { private final Map cache = new HashMap<>(); private final MetadataProvider delegate; public UUIDTypeInsertingMetadataProvider(MetadataProvider delegate) { this.delegate = delegate; } @Override public Map
不使用JPA的人的解决方案。
之前:
后: