我使用Spring Boot 1.4.1(包括Hibernate 5)和Postgres 9.6,我试图创建一个具有UUID ID的实体但是使用Postgres' UUID代而不是Hibernate代。许多类似的问题都说将列类型设置为pg-uuid
。这似乎适用于非数据库生成的ID列,但当我尝试将其用于ID列时,我得到了
org.hibernate.id.IdentifierGenerationException: unrecognized id type : pg-uuid -> java.util.UUID
所以看起来Hibernate正确地应用了类型,但没有转换它。
以下是我的实体的ID列的设置方式:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@org.hibernate.annotations.Type(type="pg-uuid")
private UUID id;
该表的设置类似于以下内容(已安装uuid-ossp
)
create table example (
id UUID NOT NULL DEFAULT uuid_generate_v1mc(),
...
);
我希望让数据库生成UUID并且不想使用Hibernate的生成策略。有没有办法让这个工作?
答案 0 :(得分:1)
解决此问题的一种方法是创建实现ResultSetIdentifierConsumer
的自定义UserType。对于一个快速而肮脏的示例,创建一个名为PostgresIdUUIDType
的类,在实现接口时扩展PostgresUUIDType
:
public class PostgresIdUUIDType extends PostgresUUIDType implements ResultSetIdentifierConsumer {
// Naively look for a name that contains "id" in it, case insensitive
private static final Pattern idPattern = Pattern.compile("id", Pattern.CASE_INSENSITIVE);
public String getName() {
return "pg-id-uuid";
}
@Override
public UUID consumeIdentifier(final ResultSet resultSet) throws IdentifierGenerationException {
try {
final int columnCount = resultSet.getMetaData().getColumnCount();
for (int i = 1; i <= columnCount; i++) {
int columnType = resultSet.getMetaData().getColumnType(i);
// Postgres driver maps UUID to OTHER
if (Types.OTHER == columnType) {
final String name = resultSet.getMetaData().getColumnName(i);
if (idPattern.matcher(name).matches()) {
return nullSafeGet(resultSet, name, new WrapperOptions() {
@Override
public boolean useStreamForLobBinding() {
return false;
}
@Override
public LobCreator getLobCreator() {
return null;
}
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(final SqlTypeDescriptor sqlTypeDescriptor) {
return PostgresUUIDSqlTypeDescriptor.INSTANCE;
}
});
}
}
}
throw new IdentifierGenerationException("Could not find id column");
} catch (SQLException e) {
throw new IdentifierGenerationException("Error converting type", e);
}
}
}
然后在您的实体中,定义自定义类型并将其用于您的ID列,如下所示:
@TypeDefs({@TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class) })
@Entity
public class Example {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@org.hibernate.annotations.Type(type="pg-id-uuid")
private UUID id;
...
}
到目前为止,这似乎适用于我的有限测试。最大的问题是PostgresIdUUIDType
天真地假设UUID
ID列是名称中第一个带'id'的列,不区分大小写。如果有人想知道如何更好地确定哪一列实际上是ID列,我会很感激调整。
答案 1 :(得分:1)
答案 2 :(得分:-1)
将策略GenerationType.AUTO
(默认)用于@GeneratedValue
@Entity
@Table("custom")
data class Custom(
@Id @GeneratedValue @Column(name = "column_uuid") val columnUUID: UUID
)
GL