【问题标题】:How do I cascade saves through a many to many relationship with hibernate?如何通过与休眠的多对多关系级联保存?
【发布时间】:2012-09-13 15:03:57
【问题描述】:

我的数据库中有一个多对多(带有连接表)关系,我需要在休眠中建模。

我对数据库中的所有三个表都有 POJO 类,因为连接表包含的不仅仅是映射信息。

我的问题发生在 A 类的 save() 上,其中 A 类被告知要级联到 AB 类(连接表),AB 类被告知要级联到 B 类,但是当它到达保存 AB 的地步时表 A 的外键引用为空。

最后,我希望能够在 TableA 类的实例上调用 save() 并让它保存所有三个表。

Table Diagram

表 A 映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.example.dbtables.TableA" table="Table A">
        <id name="id" type="int">
            <column name="id" />
            <generator class="sequence">
                <param name="sequence">table_a_seq</param>
            </generator>
        </id>
        <natural-id>
        <property name="data1" type="int">
            <column name="DATA1" not-null="true" />
        </property>
        <property name="data2" type="string">
            <column name="DATA2" length="16" not-null="true" />
        </property>
        </natural-id>
        <set name="tableAB" cascade="save-update" table="TableAB" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="Table_AB_ID" not-null="true" />
            </key>
            <one-to-many class="com.example.dbtables.TableAB" />
        </set>
    </class>
</hibernate-mapping>

表 AB 映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.example.dbtables.TableAB" table="Table AB">
        <id name="id" type="int">
            <column name="id" />
            <generator class="sequence">
                <param name="sequence">table_ab_seq</param>
            </generator>
        </id>
        <natural-id>
        <many-to-one name="tableA" class="com.example.dbtables.TableA" fetch="select">
            <column name="Table_A_ID" not-null="true" />
        </many-to-one>
        <many-to-one name="tableB" cascade="save-update" class="com.example.dbtables.TableB" fetch="select">
            <column name="Table_B_ID" not-null="true" />
        </many-to-one>
        <property name="data1" type="int">
            <column name="DATA1" not-null="true" />
        </property>
            <property name="data2" type="int">
            <column name="DATA2" not-null="true" />
        </property>
        </natural-id>
    </class>
</hibernate-mapping>

表 B 映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.examples.dbtables.TableB" table="Table B">
        <id name="id" type="int">
            <column name="id" />
            <generator class="sequence">
                <param name="sequence">table_b_seq</param>
            </generator>
        </id>
        <natural-id>
        <property name="data1" type="string">
            <column name="DATA1" length="16" />
        </property>
        <property name="data2" type="java.lang.Integer">
            <column name="DATA2" />
        </property>
        </natural-id>
        <set name="TableAB" table="Table AB" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="Table_AB_ID" not-null="true" />
            </key>
            <one-to-many class="com.example.dbtables.TableAB" />
        </set>
    </class>
</hibernate-mapping>

感谢您提供的任何帮助。如果您需要澄清或更多信息,请告诉我。

编辑:我的问题是从 AB -> 到 A 的引用没有正确填充。感谢所有提供帮助的人,此问题已得到解决。

【问题讨论】:

    标签: java hibernate postgresql orm many-to-many


    【解决方案1】:
      A a = new A();
      B b = new B();
      AB ab = new AB();
      ab.setA(a);
      ab.setB(b);
      a.setAB(ab);
      b.setAB(ab);
    
      save(a);  
    

    这个例子不起作用?你有什么例外吗?
    编辑
    查看这个 Hibernate 文档 Chapter 5. Basic O/R Mapping 到章节 5.1.4.1。生成器
    PostgreSQL 不支持 identity 生成类型。
    使用 sequence 生成而不是 identity 或其他东西

    【讨论】:

    • 我没有收到异常,但我收到一条错误消息,指出无法在表 AB 上保存,因为它违反了非空约束。您提供的示例基本上就是我正在做的,但我正在使用 JAXB 将一些我已经拥有的数据膨胀到我的类中。
    • 我记得这个错误`它违反了非空约束`。这意味着 AB 中的 A 或 B 为空,或者 A 或 B 中的 AB 为空。在保存之前调试您的对象
    • 是的,这就是我看到的错误。你是什​​么意思“保存前调试你的对象”?我知道表 A 的 id 在表 AB 中为空,因为级联沿着链向下走并且表 A 尚未保存。
    • 我注意到,我已经修复了示例中的生成器部分,但是当我在代码库中更改它们时,我仍然遇到了同样的问题。
    【解决方案2】:

    问题是 AB -> A 之间的反向引用没有正确填充到我的代码中。感谢 Ilya 的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-31
      • 2015-12-22
      相关资源
      最近更新 更多