2012-02-08 66 views
2

我有一個實體在Oracle模式中持久化。在DB插入中,觸發器通過使用DB序列來生成實體ID。使用觸發器是強制性的,因爲它還更新對於傳統組件重要的ID生成序列(日誌表類型)旁邊的另一個表。Oracle之前插入觸發器和Hibernate ID生成器設置

如何在我的實體映射中配置Hibernate ID生成器?

尋找類似的問題#1的時候,我找到了一些解決方案,不適合我的情況:

  1. 直接使用順序:<generator class="sequence">...</generator>。這是不可能的,因爲其餘觸發代碼不會被執行
  2. 使用<generator class="select">...</generator>這意味着在插入後,Hibernate使用另一個唯一屬性(根據Hibernate-3.3手冊5.1.4.6)選擇實體。這在這裏也是不可能的,因爲沒有其他獨特的列,並且不支持使用一組屬性。
  3. 在撥打save()之前使用<generator class="assigned">...</generator>並設置假ID。此ID將被DB觸發器忽略,並且生成的DB行將具有正確的ID。但是,我的Java實例不會有這個解決方案,因爲它對觸發器的實現做出了假設。

是否有解決此問題的好方法?

+0

什麼是標識符?它返回插入的標識號 – Firo 2012-02-08 16:21:18

+1

某些東西聽起來如果與該數據庫觸發器有關,應該只寫入一個序列值,如果沒有在插入中提供,例如'IF:new .pk_id IS NULL然後選擇my_seq.NEXTVAL INTO:new.pk_id FROM DUAL; END IF;' - 然後觸發器的其餘部分可以使用ID,無論它是由觸發器還是由Hibernate提供。 – 2012-02-10 06:32:09

+0

好吧,對不起已經回答了這個問題: @Firo:「身份」不支持Oracle(http://www.roseindia.net/hibernate/hibernateidgenera torelement.shtml) – rainer198 2012-07-09 15:30:22

回答

0

生成ID和更新其他表應該是單獨的任務。 您可以直接使用該序列,只在觸發器中保留「更新其他表」代碼。

爲什麼不能完成這個任何特定的原因?

+0

至少,必須執行觸發器,因爲它會更新另一個表(請參閱我今天的評論)。另一方面,我無法更改觸發器代碼,因爲其他應用程序期望觸發器正在調用序列。 – rainer198 2012-07-09 15:41:32

+0

您可以將觸發器更改爲只填充ID,如果它是NULL。然後它也可以被其他應用程序使用。 – jva 2012-07-09 16:09:08

0

<generator class="select">是更正確的解決方案。事實上,你不能選擇自動生成的值只是顯示了與ypu模型和發電機恕我直言的選擇問題。您可以嘗試使用<generator class="sequence-identity">,但正如我在javadocs(org.hibernate.id.SequenceIdentityGenerator()中提到的,根據我的經驗,對Oracle驅動程序中的getGeneratedKeys的支持很不穩定,或者至少在幾年前我第一次開發時並測試該生成器

+0

那麼,正如我所描述的,我沒有其他獨特的列可以用於這個subsequenz選擇和組合不支持。 – rainer198 2012-07-09 16:00:07

+0

組合*被*支持。將您想要用作唯一鍵的屬性標記爲@NaturalId,並且選擇生成器將自動將其用於生成的主鍵檢索。我的觀點只是,這也是恕我直言,是一個不好的數據庫設置。我的第二點是,你在列表中缺少選項號(4),它將使用' 2012-07-09 18:37:00

+0

@SteveEbersole在Hibernate 3.6.10下,試圖使用'select'生成器具有多個標註爲「@ NaturalId」的列產生'org.hibernate.id.IdentityGenerationException:select generator當前不支持複合自然標識屬性;需要在發電機參數中指定[鍵]。你能澄清哪個版本的Hibernate支持複合自然鍵的這個生成器策略嗎? – Tim 2015-02-03 16:08:13