簡體   English   中英

Oracle中CHAR主鍵列上的休眠和填充

[英]Hibernate and padding on CHAR primary key column in Oracle

我在Oracle中使用帶有char(6)列的Hibernate時遇到了一些麻煩。 這是表的結構:

CREATE TABLE ACCEPTANCE
(
   USER_ID char(6) PRIMARY KEY NOT NULL,
   ACCEPT_DATE date
);

對於用戶標識少於6個字符的記錄,我可以在使用SQuirreL運行查詢時選擇它們而不填充用戶標識。 如果存在用戶ID為“abc”的記錄,則以下IE返回記錄。

select * from acceptance where user_id = "abc"

不幸的是,當通過Hibernate(JPA)進行選擇時,以下內容返回null:

em.find(Acceptance.class, "abc");

如果我填充值,它會返回正確的記錄:

em.find(Acceptance.class, "abc   ");

我正在處理的模塊從用戶系統的其他部分取消用戶ID。 是否有更好的方法讓Hibernate工作,而不是在將代碼用於將用戶ID調整到一定長度之后再將其提供給Hibernate? (如果長度發生變化,可能會出現維護問題)

這是上帝告訴你永遠不要使用CHAR()作為主鍵的方式:-)

但是,嚴重的是,由於您的user_id在您的實體中被映射為String,因此Hibernate的Oracle方言將其轉換為varchar 由於Hibernate為其所有查詢使用預處理語句,因此該語義會延續(與SQuirreL不同,其中值被指定為文字,因此以不同方式進行轉換)。

基於Oracle 類型轉換規則,然后將列值提升為varchar2並進行比較; 因此你沒有記錄。

如果您無法更改基礎列類型,則最佳選擇可能是使用Oracle方言支持的HQL查詢和rtrim()函數。

為什么你的模塊從系統的其他部分獲得未填充的值?

根據我的理解,如果系統的其他部分不改變PK,他們應該從數據庫中讀取6個字符,並在整個過程中傳遞6個字符 - 這沒關系。 唯一的例外是生成PK時,在這種情況下可能需要填充。

您可以避免這個問題(通過每次必要時修剪或填充值),但它不能解決您的PK未得到一致處理的問題。 要提前解決問題,您必須更進一步

  • 總是從模塊的其他部分接收6個字符
  • 使用varchar2正確處理動態大小

如果你不能提前解決問題,那么你確實需要

  • 必要時在周圍添加修剪/填充
  • 如果有的話,在DAO中添加修剪/填充
  • 如果有效,請在用戶類型中添加修剪/填充(來自N. Hughes的建議)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM