Postgres和Oracle与Hibernate的兼容性
在某些情況下,您的JEE應用程序需要支持Postgres和Oracle作為數據庫。
Hibernate應該在這里完成工作,但是有些細節值得一提。
在為已經運行Oracle的應用程序啟用Postgres時,我遇到了以下棘手的部分:
- BLOBs支持,
- CLOBs支持,
- Oracle不知道Boolean類型(使用Integer ),并且
- DUAL表。
這些是我必須使用的技巧,以使@Entity類在這兩種方法上運行。
請注意,我已經將Postgres 9.3和Hibernate 4.2.1.SP1一起使用了。
BLOB支持
Postgres的問題在于它提供兩種類型的BLOB存儲:
- bytea –表中存儲的數據
- oid –表僅保存存儲在其他位置的數據的標識符
我猜在大多數情況下,您都可以像我一樣使用bytea 。 據我所讀,另一個用于一些大數據(千兆字節),因為它支持IO操作流。
好吧,聽起來很高興有這樣的支持,但是在這種情況下使用Hibernate可能會帶來很多問題(由于需要使用特定的批注),尤其是在您嘗試與Oracle兼容的情況下。
要在此處查看問題,請參見StackOverflow:byte []的正確休眠注釋
所有組合均在此處描述:
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其中@Type(PBA)代表@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")和@Type(BT)代表: @Type(type="org.hibernate.type.BinaryType") 。
這些會導致各種Postgres錯誤,例如:
錯誤:列“ foo”的類型為oid,但表達式的類型為bytea
要么
錯誤:列“ foo”的類型為bytea,但表達式的類型為oid
好吧,似乎有一個解決方案,它仍然包括對Hibernate庫的修補(我在使用3.rd party庫時看到的最后一個選擇)。
Hibernate的專家們還引用了官方博客文章,主題是PostgreSQL和BLOB 。 仍然在博客文章中描述的解決方案似乎對我不起作用,并且基于這些評論,似乎對更多人無效。
BLOB已解決
好,現在是樂觀的部分。
經過大量調試后,我最終得到了Entity定義,如下所示:
@Lob private byte[] foo;Oracle對此沒有任何麻煩,而且我不得不以一種方式自定義Postgres方言:
public class PostgreSQLDialectCustom extends PostgreSQL82Dialect {@Overridepublic SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {if (sqlTypeDescriptor.getSqlType() == java.sql.Types.BLOB) {return BinaryTypeDescriptor.INSTANCE;}return super.remapSqlTypeDescriptor(sqlTypeDescriptor);} }而已! 很簡單吧? 這適用于在Postgres中持久保存bytea類型的列(因為這適合我的用例)。
CLOB支持
錯誤配置中的錯誤如下所示:
org.postgresql.util.PSQLException: Bad value for type long : ...因此,首先我找到了以下解決方案(在帶有Hibernate 3.6的PostgreSQL上的String LOB上 ):
@Lob @Type(type = "org.hibernate.type.TextType") private String foo;嗯,那行得通,但僅適用于Postgres。
然后有一個建議(關于StackOverflow:Postgres具有JDBC的Postgres UTF-8克隆 )可用于:
@Lob @Type(type="org.hibernate.type.StringClobType") private String foo;那為我指明了正確的方向(有趣的是,這只是對一些答案的評論)。 它非常接近,但是在所有情況下都不適用于我,仍然導致測試出錯。
CLOB已解決
重要的是org.hibernate.type.StringClobType中的@deprecation javadocs,這使我開始工作:
@Lob @Type(type="org.hibernate.type.MaterializedClobType") private String foo;這適用于Postgres和Oracle,而無需任何進一步的黑客(在Hibernate方面)。
布爾型
Oracle不知道Boolean類型,而麻煩是Postgres知道。 由于也存在一些簡單的SQL,我最終在Postgres中遇到錯誤:
錯誤:“ foo”列的類型為布爾值,但表達式的類型為整數
我決定在Postgres中啟用從Integer到Boolean ,而不是固定所有普通的SQL位置(以論壇:自動從Integer到Boolean的轉換 ):
update pg_cast set castcontext = 'i' where oid in ( select c.oid from pg_cast c inner join pg_type src on src.oid = c.castsource inner join pg_type tgt on tgt.oid = c.casttarget where src.typname like 'int%' and tgt.typname like 'bool%');請注意,您應該按用戶權限運行SQL更新,以更新目錄(可能不是您的postgres用戶用于從應用程序進行數據庫連接),正如我在Stackoverflow上了解到的:Postgres –拒絕更新pg_catalog.pg_cast的權限 。
雙表
我遇到的Oracle中還有一個更具體的內容。 如果您使用普通的SQL,則在Oracle中提供了DUAL表(請參閱Wikipedia上的更多信息),這可能會對Postgres造成傷害。
解決方案仍然很簡單。 在Postgres中創建一個視圖,該視圖將達到類似的目的。 可以這樣創建:
create or replace view dual as select 1;結論
好吧,應該是這樣。 享受與跨數據庫兼容的JEE應用程序。
翻譯自: https://www.javacodegeeks.com/2014/03/postgres-and-oracle-compatibility-with-hibernate.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Postgres和Oracle与Hibernate的兼容性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑键盘怎么清洗如何清理笔记本电脑键盘
- 下一篇: 诺基亚G42 5G确认将于9月11日推出