Hibernate级联保存带有顺序FK的父/子

时间:2012-08-14 21:32:48

标签: hibernate parent sequence cascade

我已经阅读了很多关于这个主题的帖子,但还是无法解决它=(

我正在尝试保存父母及其与孩子有一对多关系的孩子。我相信我正在关注其他帖子的文档和其他建议。但是,我遇到的问题是,当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(下一个seq值,比如273)保存Parent对象,但是当它继续并尝试保存子对象时,而不是使用273,它只是使用0。

我无法想象如何让Hibernate使用正确的ParentId(FK)保存子对象。

您可以提供的任何帮助或任何想法将非常感谢!提前谢谢!

** 更新 ** 我终于弄清楚为什么子表中的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>

注意标记而不是之前的标记。此外,标签之外的标签已经消失(或者更确切地说是作为标签移动到id中)。

1 个答案:

答案 0 :(得分:0)

我认为在你的情况下,你应该在父类的一对多映射定义中将inverse属性设置为false。这意味着您的父实体将负责更新子表中的FK。在这种情况下,hibernte将在保存父实体后执行附加更新语句以更新子表中的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>