一些同事提出了一個問題,他們發(fā)現(xiàn)查詢執(zhí)行時間很慢,并且發(fā)現(xiàn)由于隱式類型轉(zhuǎn)換而未使用索引。kgb_uuid該表有一個用于存儲 UUID 的屬性。該列被定義為VARCHAR2并具有一個索引,用于通過 UUID 搜索行。實體中的相關(guān)字段定義為String。根據(jù) Hibernate 文檔,Hibernate 應(yīng)該將此字符串轉(zhuǎn)換為VARCHAR2Oracle 數(shù)據(jù)庫,因此應(yīng)該使用索引。但事實并非如此,如日志所示:[9/2/19 11:56:07:610 CEST] 00000177 SystemOut O2019-09-02T11:56:07,610 TRACE [ebContainer : 3] ibebcTraceInterceptor;log;;41 - 類 [MyDAO] 中的入口方法 [checkEindeutigeUUID]帶參數(shù) (MyEntity@b14745f9)[9/2/19 11:56:07:688 CEST] 00000177 SQL Z org.hibernate.engine.jdbc.spi.SqlStatementLogger logStatement 選擇 count(mytab0_.KGB_NR) as col_0_0_ from MYENTITYTABLE mytab_ where mytab_.KGB_UUID=?和 mytab_.EKN_NR=?[9/2/19 11:56:07:688 CEST] 00000177 BasicBinder Z org.hibernate.type.descriptor.sql.BasicBinder 綁定參數(shù) [1] 作為 [VARCHAR] - 795BF3B98D879358E0531C03A90ABF0A [9/2/19 11:56 :07:688 CEST] 00000177 BasicBinder Z org.hibernate.type.descriptor.sql.BasicBinder 綁定綁定參數(shù) [2] 作為 [BIGINT] - 1正如所見,字符串值被綁定為VARCHARnot as VARCHAR2,導(dǎo)致數(shù)據(jù)庫進行隱式類型轉(zhuǎn)換并且不使用索引,如 OEM 中所示(這是來自 OEM 的原始德語消息):執(zhí)行計劃的行 ID 3 中使用的謂詞 SYS_OP_C2C("mytab_"."KGB_UUID")=:B1 包含索引列“KGB_UUID”上的隱式數(shù)據(jù)類型轉(zhuǎn)換。這種隱式數(shù)據(jù)類型轉(zhuǎn)換會阻止優(yōu)化器有效地使用表“MYENTITYTABLE”上的索引。它表示使用了謂詞SYS_OP_C2C("mytab_"."KGB_UUID")=:B1,并且它包含索引基列的隱式屬性類型的對話KGB_UUID,并且該隱式類型的對話阻止優(yōu)化器有效地使用表的索引MYENTITYTABLE。我們已經(jīng)解決了在表上使用功能索引的問題,但我們?nèi)匀幌胫罏槭裁?Hibernate 提供了一種顯然不是VARCHAR2.系統(tǒng):Hibernate 4.2.21 與 Hibernate Dialect Oracle10g(根據(jù)文檔最多兼容 12 個)Oracle 12.2(現(xiàn)在不完全是,我認為是12.2,但也許只是12.1)Hibernate 版本無法升級,因為它是可與 JPA 2.0 一起使用的最后一個版本,JPA 2.0 是 Websphere Process Server 8.5 支持的 JavaEE 6 的一部分。(簡稱)實體@Entity@Table(name = "MYENTITYTABLE")public class MyEntity implements Serializable { private static final long serialVersionUID = 1L; @Id // out commented the sequence generator @Column(name="KGB_NR") private long kgbNr; @Column(name="KGB_UUID") private String kgbUuid; // <<== DEFINED AS STRING! //bi-directional many-to-one association to Ekistnutzer @ManyToOne @JoinColumn(name="EKN_NR") private EkistnutzerEntity ekistnutzer; // Other attributes not related in problem}
1 回答

青春有我
TA貢獻1784條經(jīng)驗 獲得超8個贊
最簡單的方法是擴展默認值StringType
并覆蓋sqlType
屬性,并通過注釋向?qū)嶓w屬性提供新的 Hibernate 類型@Type
。
該映射很可能VARCHAR2
是通過 Oracle Hibernate Dialect 實現(xiàn)的,因此您不應(yīng)該覆蓋默認的 Dialect 映射,因為可能存在正確使用VARCHAR2
.
因此,自定義 Hibernate 類型為您提供了控制權(quán),并允許您僅將其用于列VARCHAR
。
添加回答
舉報
0/150
提交
取消