Hibernate使用顺序FK级联保存父级/子级

Hibernate使用顺序FK级联保存父级/子级,hibernate,parent,sequence,cascade,Hibernate,Parent,Sequence,Cascade,我读过很多关于这个话题的帖子,但都没能解决它=( 我正在尝试保存具有一对多关系的父项及其子项。我相信我正在遵循其他帖子中的文档和其他建议。但是,我遇到的问题是,当Hibernate尝试保存子项记录时,它将FK的“0”插入父项,而不是实际id 父hbm.xml映射 <hibernate-mapping> <class name="ParentClass" table="PARENTTABLE"> <id name="parentid" type="java.l

我读过很多关于这个话题的帖子,但都没能解决它=(

我正在尝试保存具有一对多关系的父项及其子项。我相信我正在遵循其他帖子中的文档和其他建议。但是,我遇到的问题是,当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>
<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>
<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>

S_父表
...
...
子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>
<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>
<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>

....
....
保存对象的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);
    ...
}
private myMethod(父类p,HashSet子类){
for(儿童类儿童:儿童){
子母(p);
}
p、 setChildren(children);//参数类型已设置
sess.save(p);
...
}
因此,它将使用正确的id(下一个seq值,比如273)保存父对象,但当它尝试保存子对象时,而不是使用273,它只是使用0

我不知道如何让Hibernate使用正确的ParentId(FK)保存子对象

如果您能提供任何帮助或想法,我们将不胜感激!提前感谢

**更新** 我终于明白了为什么子表中的FK没有插入正确的值。这是由于映射定义。我在数据库上运行了反向工程,并选中了一个“生成基本类型的复合ID”框。这导致Hibernate将复合键列映射为基元类型,而不是对实体的引用.我做插页时,不知怎么搞混了

正确的子表映射应如下所示:

更新的子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>
<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>
<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中).

我认为在您的情况下,应该在父类的一对多映射定义中将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>


Hi Dimas,感谢您的回复=)。事实上,我已经试过了,但似乎没有什么不同所以我先做一个sess.save,然后再做一个sess.flush。在我的日志中,我看到当我保存时,Hibernate首先获取序列值(nextval)。然后,它会选择父记录和子记录。在这个阶段,它已经在选择子项中为parentid使用了“0”。最后,在刷新时,它插入到具有正确id的父表中,然后插入到具有“0”的子表中,我得到错误=(确定。尝试从父实体的集合定义中删除table=“CHILDTABLE”,并删除class=“ParentClass”从多到一的儿童类定义。嗨,迪马斯,谢谢你的回答和建议,但不幸的是,这也不起作用。但我确实设法弄清楚了它是什么!=)我用我所做的更新了我的问题。再次感谢!