2012-08-14 104 views
1

我已經看了很多帖子對這個話題,但一直沒能解決這個問題=(Hibernate的級聯保存父/子與測序FK

我試圖拯救父母和孩子有一個一我相信我遵循文檔和其他帖子的其他建議,但是,我遇到的問題是,當Hibernate嘗試保存子記錄時,它將FK插入「0」給父項的,而不是真正的ID。

父的hbm.xml映射

<hibernate-mapping> 
<class name="ParentClass" table="PARENTTABLE"> 
    <id name="parentid" type="java.lang.Long"> 
     <column name="PARENTID" precision="15" scale="0" /> 
     <generator class="sequence"> 
      <param name="sequence">S_PARENTTABLE</param> 
     </generator> 
    </id> 
... 
    <set name="children" table="CHILDTABLE" inverse="true" lazy="true" fetch="select" cascade="all"> 
     <key> 
      <column name="PARENTID" precision="15" scale="0" not-null="true" /> 
     </key> 
     <one-to-many class="ParentClass" /> 
    </set> 
... 
</class> 
</hibernate-mapping> 

孩子的hbm.xml映射

<hibernate-mapping> 
<class name="ChildClass" table="CHILDTABLE"> 
    <composite-id name="id" class="ChildClassId"> 
     .... 
     <key-property name="parentid" type="long"> 
      <column name="PARENTID" precision="15" scale="0" /> 
     </key-property> 
    </composite-id> 
    <many-to-one name="parent" class="ParentClass" update="false" insert="false" fetch="select"> 
     <column name="PARENTID" precision="15" scale="0" not-null="true" /> 
    </many-to-one> 
.... 
</class> 
</hibernate-mapping> 

Java代碼保存對象

private myMethod(ParentClass p, HashSet<ChildClass> children){ 
    for(ChildClass child : children){ 
     child.setParent(p); 
    } 
    p.setChildren(children); //The parameter type is Set<ChildClass> 
    sess.save(p); 
    ... 
} 

因此,這將保存正確的ID父對象(下一序列值,說273)但是當它去,並試圖保存子對象,而不是使用273,它只是使用0.

我不能figur e如何讓Hibernate用正確的ParentId(FK)保存子對象。

任何幫助你可以提供或任何想法將非常感激!提前致謝!

** UPDATE ** 我終於弄清楚爲什麼子表中的FK沒有插入正確的值。這是由於映射定義。我在我的數據庫上運行了一個反向工程師,並且選中了一個表示'生成基本類型化合成ID'的框。這導致Hibernate將複合鍵列映射爲基本類型,而不是對實體的引用。當我做插入時,這有點讓人困惑。

正確的子表映射應該看起來更像是這樣的:

更新孩子的hbm.xml映射

<hibernate-mapping> 
<class name="ChildClass" table="CHILDTABLE"> 
    <composite-id name="id" class="ChildClassId"> 
     .... 
     <key-many-to-one name="parentid" class="ParentClass" > 
      <column name="PARENTID" precision="15" scale="0" /> 
     </key-many-to-one> 
    </composite-id> 
</class> 
</hibernate-mapping> 

通知的標籤,而不是從之前的標籤。此外,標籤外的標籤已經消失(或者更確切地說,將標籤作爲標籤移動到標識中)。

回答

0

我認爲在你的情況下,你應該在父類的一對多映射定義中將inverse屬性設置爲false。這意味着您的父實體將負責更新子表中的FK。在這種情況下,休眠將在保存父實體後執行額外的更新語句以更新子表中的FK。

<set name="children" inverse="false" lazy="true" fetch="select" cascade="all"> 
     <key> 
      <column name="PARENTID" precision="15" scale="0" not-null="true" /> 
     </key> 
     <one-to-many class="ParentClass" /> 
</set> 
+0

嗨迪馬斯,感謝您的回覆=)。我實際上已經嘗試過了,它似乎沒有區別..? = |所以我做了一個sess.save然後sess.flush。在我的日誌中,我看到當我進行保存時,Hibernate首先獲取序列值(nextval)。然後,它會爲父和子記錄進行選擇。在這個階段,它已經在選擇孩子時使用'0'作爲參數。然後最後,在刷新,它插入到正確的ID,然後它插入到子表,但與'0',我得到我的錯誤=( – ZeroK178 2012-08-15 15:48:17

+0

好吧。嘗試從父實體的集合定義中移除table =「CHILDTABLE」,並從子類的多對一定義中移除class =「ParentClass」。 – dimas 2012-08-16 11:08:47

+0

嗨迪馬斯,感謝您的回覆和建議,但不幸的是,這也沒有奏效。但我設法弄清楚它是什麼! =)我用我所做的更新了我的問題。再次感謝! – ZeroK178 2012-08-20 19:41:51