32

UUID を主キーとして使用するエンティティを PostgreSQL に永続化しようとしています。私はそれをプレーンな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 年 7 月 3 日午後 12 時 15 分)

まあ、まあ、まあ...JTDSドライバー(v1.2.5)を使用してSQLサーバー2008 R2でまったく同じコード(プレーンUUID、変換なし-上記のコードの最初のバージョン)をテストしたのはちょっと興味深いです。 、それは魅力として機能したと思います(もちろん、persistence.xmlで接続関連の情報を変更する必要がありました)。

さて、これは PostgreSQL 固有の問題ですか、それとも何ですか?

4

6 に答える 6

40

残念ながら、PostgreSQL JDBC ドライバーは、非 JDBC 標準型コードを表す方法を選択しました。それらはすべて Type.OTHER に単純にマップされます。簡単に言うと、(postgres 固有の uuid データ型の列への) UUID マッピングを処理するために、特別な Hibernate 型マッピングを有効にする必要があります。

@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でカバーされています

于 2012-10-10T17:16:40.003 に答える
15

Hibernate 5.1.x で動作させるには、Steve Ebersole のコメントをフォローしてください。

@Id
@GeneratedValue
@Column( columnDefinition = "uuid", updatable = false )
public UUID getId() {
    return id;
}
于 2016-12-20T04:38:17.217 に答える
1

Oleg によって提案された解決策は、私にとっては完全には機能しませんでした (null 値を保持しようとすると失敗しました)。これは、null 値でも機能する微調整されたソリューションです。

私の場合、EclipseLink を使用していますが、Hibernate を使用している場合は、これは必要ないかもしれません。

public class UuidConverter implements AttributeConverter<UUID, Object> {
    @Override
    public Object convertToDatabaseColumn(UUID uuid) {
        PGobject object = new PGobject();
        object.setType("uuid");
        try {
            if (uuid == null) {
                object.setValue(null);
            } else {
                object.setValue(uuid.toString());
            }
        } catch (SQLException e) {
            throw new IllegalArgumentException("Error when creating Postgres uuid", e);
        }
        return object;
    }

    @Override
    public UUID convertToEntityAttribute(Object dbData) {
        return (UUID) dbData;
    }
}
于 2014-07-30T08:27:39.407 に答える
0

postgresql url 接続に次のフラグを追加します: ?stringtype=unspecified

そのように

jdbc:postgresql://localhost:5432/yourdatabase?stringtype=unspecified

于 2017-12-07T11:17:13.053 に答える