hibernate 3.1およびJPAアノテーションを使用するアプリケーションがあります。これには、byte []属性を持つオブジェクトがいくつかあります(サイズが1k〜200k)。JPA @Lobアノテーションを使用し、Hibernate 3.1はすべての主要なデータベースでこれらを正常に読み取ることができます-JDBC Blobベンダーの特性を(本来のように)隠すようです。
@Entity
public class ConfigAttribute {
@Lob
public byte[] getValueBuffer() {
return m_valueBuffer;
}
}
hibernate 3.5 がpostgresqlのこのアノテーションの組み合わせを回避する(そして修正しない)ことを発見したとき、3.5にアップグレードする必要がありました (回避策はありません)。今のところ明確な修正は見つかりませんでしたが、@ Lobを削除するだけでpostgresql型byteaが使用されていることに気付きました(これは機能しますが、postgresでのみ機能します)。
annotation postgres oracle works on
-------------------------------------------------------------
byte[] + @Lob oid blob oracle
byte[] bytea raw(255) postgresql
byte[] + @Type(PBA) oid blob oracle
byte[] + @Type(BT) bytea blob postgresql
once you use @Type, @Lob seems to not be relevant
note: oracle seems to have deprecated the "raw" type since 8i.
主要なデータベース間で移植可能な単一の注釈付きクラス(blobプロパティ付き)を作成する方法を探しています。
- byte []プロパティに注釈を付けるポータブルな方法は何ですか?
- これは、一部の最近のバージョンのhibernateで修正されていますか?
更新:このブログを 読んだ後、私はようやくJIRAの問題の元の回避策が何であったかを理解しました:どうやら@Lobをドロップし、プロパティに次のように注釈を付けることになっています:
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
byte[] getValueBuffer() {...
しかし、これは私にとっては機能しません -私はまだbyteaの代わりにOIDを取得しています。ただし、oidを必要としているように思われたJIRAの問題の作成者には役立ちました。
A.ガルシアからの回答の後、私はこのコンボを試しましたが、実際にはpostgresqlでは機能しますが、Oracleでは機能しません。
@Type(type="org.hibernate.type.BinaryType")
byte[] getValueBuffer() {...
私が本当に必要なことは、@ postgresqlで@ org.hibernate.annotations.Typeの組み合わせ(@Lob + byte []がマッピングされる)を制御することです。
以下は、MaterializedBlobType(SQLタイプBlob)の3.5.5.Finalのスニペットです。Steveのブログによると、postgresqlではbytea(理由は聞かないでください)にはStreamsを、oidsにはpostgresqlのカスタムBlobタイプを使用することを求めています。また、JDBCでのsetBytes()の使用はbytea(過去の経験から)にも使用できることに注意してください。したがって、これは、use-streamが両方とも「bytea」を想定している影響がない理由を説明しています。
public void set(PreparedStatement st, Object value, int index) {
byte[] internalValue = toInternalFormat( value );
if ( Environment.useStreamsForBinary() ) {
// use streams = true
st.setBinaryStream( index,
new ByteArrayInputStream( internalValue ), internalValue.length );
}
else {
// use streams = false
st.setBytes( index, internalValue );
}
}
これは結果として:
ERROR: column "signature" is of type oid but expression is of type bytea
更新 次の論理的な質問は、「なぜテーブル定義を手動でbyteaに変更しないのか」であり、(@ Lob + byte [])を保持しますか?これはありません、仕事をUNTILあなたは[]ヌル・バイトを格納しよう。postgreSQLドライバーがOIDタイプ式であり、列タイプがbyteaであると考えるのは、PGドライバーが予期するJDBC.setBytes(null)の代わりにhibernateが(正しく)JDBC.setNull()を呼び出すためです。
ERROR: column "signature" is of type bytea but expression is of type oid
hibernateの型システムは現在「進行中の作業」です(3.5.5非推奨コメントによる)。実際、3.5.5のコードの多くは廃止されており、PostgreSQLDialectをサブクラス化するときに何を見ればよいかを知るのは困難です。
postgresqlのAFAKT、Types.BLOB / 'oid'は、OIDスタイルのJDBCアクセスを使用するカスタムタイプにマッピングする必要があります(PostgresqlBlobTypeオブジェクトとMaterializedBlobTypeではない)。実際にpostgresqlでBlobを正常に使用したことはありませんが、byteaは単に期待どおりに機能することを知っています。
私は現在、BatchUpdateExceptionを見ています。ドライバがバッチ処理をサポートしていない可能性があります。
2004年の素晴らしい引用:「とりとめのない話をまとめると、Hibernateを変更する前に、JDBCドライバーがLOBを適切に実行するのを待つ必要があると私は言います。」
参照:
- https://forum.hibernate.org/viewtopic.php?p=2393203
- https://forum.hibernate.org/viewtopic.php?p=2435174
- http://hibernate.atlassian.net/browse/HHH-4617
- http://postgresql.1045698.n5.nabble.com/Migration-to-Hibernate-3-5-final-td2175339.html
- https://jira.springframework.org/browse/SPR-2318
- https://forums.hibernate.org/viewtopic.php?p=2203382&sid=b526a17d9cf60a80f13d40cf8082aafd
- http://virgo47.wordpress.com/2008/06/13/jpa-postgresql-and-bytea-vs-oid-type/