Saya memiliki aplikasi yang menggunakan anotasi hibernate 3.1 dan JPA. Ini memiliki beberapa objek dengan atribut byte [] (ukuran 1k - 200k). Ia menggunakan anotasi JPA @Lob, dan hibernate 3.1 dapat membacanya dengan baik di semua database utama - tampaknya menyembunyikan kekhasan vendor JDBC Blob (sebagaimana mestinya).
@Entity
public class ConfigAttribute {
@Lob
public byte[] getValueBuffer() {
return m_valueBuffer;
}
}
Kami harus meningkatkan ke 3.5, ketika kami menemukan bahwa hibernate 3.5 rusak (dan tidak akan memperbaiki) kombinasi anotasi ini di postgresql (tanpa solusi). Saya belum menemukan perbaikan yang jelas sejauh ini, tetapi saya perhatikan bahwa jika saya hanya menghapus @Lob, itu menggunakan bytea tipe postgresql (yang berfungsi, tetapi hanya pada 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.
Saya mencari cara untuk memiliki kelas beranotasi tunggal (dengan properti blob) yang portabel di seluruh database utama.
- Apa cara portabel untuk menganotasi properti byte []?
- Apakah ini diperbaiki di beberapa versi hibernasi terbaru?
Pembaruan: Setelah membaca blog ini, saya akhirnya menemukan solusi asli dalam masalah JIRA: Rupanya Anda seharusnya menghapus @Lob dan memberi anotasi pada properti sebagai:
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
byte[] getValueBuffer() {...
Namun, ini tidak berhasil untuk saya - saya masih mendapatkan OID, bukan bytea; namun hal itu berhasil untuk penulis masalah JIRA, yang sepertinya menginginkan oid.
Setelah jawaban dari A. Garcia, saya kemudian mencoba kombo ini, yang sebenarnya berfungsi pada postgresql, tetapi tidak pada oracle.
@Type(type="org.hibernate.type.BinaryType")
byte[] getValueBuffer() {...
Yang benar-benar perlu saya lakukan adalah mengontrol @ org.hibernate.annotations. Ketik kombinasi (@Lob + byte [] yang dipetakan) ke (di postgresql).
Berikut adalah potongan dari 3.5.5. Final dari MaterializedBlobType (sql type Blob). Menurut blog Steve, postgresql ingin Anda menggunakan Streams untuk bytea (jangan tanya saya mengapa) dan jenis Blob kustom postgresql untuk oids. Perhatikan juga bahwa menggunakan setBytes () di JDBC juga untuk bytea (dari pengalaman sebelumnya). Jadi ini menjelaskan mengapa use-stream tidak memengaruhi mereka berdua menganggap '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 );
}
}
Ini menghasilkan:
ERROR: column "signature" is of type oid but expression is of type bytea
Perbarui Pertanyaan logis berikutnya adalah: "mengapa tidak mengubah definisi tabel secara manual ke bytea" dan menyimpan (@Lob + byte [])? Ini tidak bekerja, UNTIL Anda mencoba untuk menyimpan null byte []. Yang menurut driver postgreSQL adalah ekspresi tipe OID dan tipe kolom adalah bytea - ini karena hibernate (dengan benar) memanggil JDBC.setNull () dan bukan JDBC.setBytes (null) yang diharapkan driver PG.
ERROR: column "signature" is of type bytea but expression is of type oid
Sistem tipe dalam mode hibernasi saat ini sedang dalam proses (menurut komentar penghentian 3.5.5). Faktanya, begitu banyak kode 3.5.5 yang tidak digunakan lagi, sulit untuk mengetahui apa yang harus dilihat saat melakukan sub-klasifikasi PostgreSQLDialect).
AFAKT, Types.BLOB / 'oid' pada postgresql harus dipetakan ke beberapa tipe kustom yang menggunakan akses JDBC gaya OID (yaitu objek PostgresqlBlobType dan NOT MaterializedBlobType). Saya tidak pernah benar-benar berhasil menggunakan Blobs dengan postgresql, tetapi saya tahu bahwa bytea hanya berfungsi seperti yang saya harapkan.
Saat ini saya melihat BatchUpdateException - kemungkinan driver tidak mendukung batching.
Kutipan bagus dari 2004: "Untuk menyimpulkan ocehan saya, saya akan mengatakan mereka kita harus menunggu driver JDBC melakukan LOB dengan benar sebelum mengubah Hibernate."
Referensi:
- 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/