2011-02-23 66 views
2

我在插入觸發器之前和之後使用幾個表中的「ID_NAME-000001」形式生成ID(主鍵)。目前,這些pojos的hibernate generator類的值是,分配爲。一個隨機字符串被分配給要被持久化的對象,當它被hibernate插入時,觸發器會分配一個正確的id值。休眠觸發器生成的ID(MySQL)問題

這種方法的問題是我無法檢索持久對象,因爲該ID只存在於數據庫中,而不存在於我剛剛保存的對象中。

我想我需要創建一個自定義生成器類,可以檢索由觸發器分配的id值。我已經看到了一個用於oracle的例子(https://forum.hibernate.org/viewtopic.php?f=1&t=973262),但我還沒有能夠爲MySQL創建類似的東西。有任何想法嗎?

感謝,

更新:

看來,這是一種常見的,但是,沒有解決問題。我最終創建了一個新列,作爲使用選擇生成器類的唯一鍵。

回答

1

希望這不會引發神聖的戰爭是否使用代用鑰匙。但現在是時候在這裏打開對話。

另一種方法是,使用生成的密鑰作爲代理鍵併爲觸發器分配的id分配一個新字段。代理鍵是主鍵。您具有邏輯上命名的密鑰(例如,在您的示例中爲「ID_NAME-000001」)。所以你的數據庫行將有2個鍵,主鍵是代理鍵(可以是UUID,GUID,運行號)。 通常這種方法是可取的,因爲它可以更好地適應新的變化。 說,你有這些使用代理鍵的行,而不是使用生成的ID作爲自然鍵。

代理鍵:

id: "2FE6E772-CDD7-4ACD-9506-04670D57AA7F", logical_id: "ID_NAME-000001", ... 

自然鍵:

id: "ID_NAME-000001", ... 

當後一個新的需求需要logical_id可編輯,審覈(被它改變,誰改變了它時)或轉讓,將logical_id作爲主鍵會給你帶來麻煩。通常你不能改變你的主鍵。當你的數據庫中已經有很多數據,並且由於新的需求而必須遷移數據時,這是非常不利的。

隨着代理鍵解決方案,這將是很容易,你只需要添加

id: "2FE6E772-CDD7-4ACD-9506-04670D57AA7F", logical_id: "ID_NAME-000001", valid: "F", ... 
id: "0A33BF97-666A-494C-B37D-A3CE86D0A047", logical_id: "ID_NAME-000001", valid: "T", ... 

MySQL不支持序列(IMO自動增量是無法相比的序列)。它不同於Oracle/PostgreSQL的順序。我想這就是爲什麼很難將解決方案從Oracle數據庫移植到MySQL的原因。 PostgeSQL的確如此。

+0

感謝您的建議。當我添加新列(自定義UUID)時,我發現在選擇主鍵時出現錯誤。不幸的是,在這個階段無法糾正這個問題。 – greatgoron 2011-02-26 06:55:28

+0

是的,我同意。當您仍處於設計階段時,更換容易。當您的應用程序處於製作和支持狀態時,可能需要花費很大力氣才能更改密鑰。 – 2011-02-28 04:12:53