使用 JPA 在 PostgreSQL 中保留 UUID

新手上路,请多包涵

我试图在 PostgreSQL 中保留一个使用 UUID 作为主键的实体。我尝试将其作为普通 UUID 保留:

 @Id
@Column(name = "customer_id")
private UUID id;

通过以上,我得到这个错误:

 ERROR: column "customer_id" is of type uuid but expression is of type bytea
Hint: You will need to rewrite or cast the expression.
Position: 137

我还尝试将 UUID 保留为 byte[] 但无济于事:

 @Transient
private UUID id;

@Id
@Column(name = "customer_id")
@Access(AccessType.PROPERTY)
@Lob
protected byte[] getRowId() {
    return id.toString().getBytes();
}

protected void setRowId(byte[] rowId) {
    id = UUID.fromString(new String(rowId));
}

如果我删除@Lob,我得到的错误与上面发布的错误相同。但是应用@Lob 后,错误会稍微更改为:

 ERROR: column "customer_id" is of type uuid but expression is of type bigint
Hint: You will need to rewrite or cast the expression.
Position: 137

不能做这么简单的事情,我感到非常难过!

我在 PostgreSQL 9.1 中使用 Hibernate 4.1.3.Final。

我已经看到很多关于 SO 的问题或多或少都涉及相同的问题,但它们都是旧的,而且似乎没有一个有直接的答案。

我想以一种标准的方式实现这一点,而不是诉诸于丑陋的黑客。但是,如果这只能通过(丑陋的)黑客来实现,那么这可能就是我要做的。但是,我不想将 UUID 作为 varchar 存储在数据库中,因为这对性能不利。另外,如果可能的话,我不想在我的代码中引入 Hibernate 依赖项。

任何帮助将不胜感激。

更新 1 (2012-07-03 12:15 pm)

好吧,好吧…我用 SQL Server 2008 R2 使用 JTDS 驱动程序 (v1.2.5) 测试了完全相同的代码(纯 UUID,无转换——上面发布的代码的第一个版本),这有点有趣,你猜怎么着,它很有魅力(当然我不得不更改 persistence.xml 中与连接相关的信息)。

现在,这是一个特定于 PostgreSQL 的问题还是什么?

原文由 ehsanullahjan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 908
2 个回答

不幸的是,PostgreSQL JDBC 驱动程序选择了一种表示非 JDBC 标准类型代码的方式。他们只是将它们全部映射到 Types.OTHER。长话短说,您需要启用特殊的 Hibernate 类型映射来处理 UUID 映射(到 postgres 特定的 uuid 数据类型的列):

 @Id
@Column(name = "customer_id")
@org.hibernate.annotations.Type(type="org.hibernate.type.PostgresUUIDType")
private UUID id;

或更简洁:

 @Id
@Column(name = "customer_id")
@org.hibernate.annotations.Type(type="pg-uuid")
private UUID id;

另一个(更好的)选项是将 org.hibernate.type.PostgresUUIDType 注册为所有公开为 java.util.UUID 的属性的默认 Hibernate 类型映射。这包含在文档@ http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch06.html#types-registry

原文由 Steve Ebersole 发布,翻译遵循 CC BY-SA 3.0 许可协议

JPA 2.1 提供了一种非常简单的方法来使用 PostgreSQL uuid 列类型和 java.util.UUID 作为相应实体字段的类型:

 @javax.persistence.Converter(autoApply = true)
public class PostgresUuidConverter implements AttributeConverter<UUID, UUID> {

    @Override
    public UUID convertToDatabaseColumn(UUID attribute) {
        return attribute;
    }

    @Override
    public UUID convertToEntityAttribute(UUID dbData) {
        return dbData;
    }

}

只需将此类添加到您的持久性配置并使用 @Column(columnDefinition="uuid") 注释 UUID 字段。

原文由 Oleg Estekhin 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题