Hibernate 使用空集休眠多对多映射

Hibernate 使用空集休眠多对多映射,hibernate,Hibernate,我有以下情况: 表A和表B具有多对多关系。 类A映射到表A,类B映射到表B,并且有一个联接表AB。 A类有一套B类,B类有一套A类。 我有三个不同的用户界面来创建/更新A、B和AB。 当我在A的UI中加载A的信息时,我不想加载B的列表(性能原因)。因此,在保存A时,我只得到与A相关的信息,并且Set为null。 当我保存A的这个实例时,它会删除A和B之间的所有现有映射。 hibernate允许这样的保存吗?或者,我们是否总是必须在保存数据集之前填充数据集 数据库表A: aid | data -

我有以下情况: 表A和表B具有多对多关系。 类A映射到表A,类B映射到表B,并且有一个联接表AB。 A类有一套B类,B类有一套A类。 我有三个不同的用户界面来创建/更新A、B和AB。 当我在A的UI中加载A的信息时,我不想加载B的列表(性能原因)。因此,在保存A时,我只得到与A相关的信息,并且Set为null。 当我保存A的这个实例时,它会删除A和B之间的所有现有映射。 hibernate允许这样的保存吗?或者,我们是否总是必须在保存数据集之前填充数据集


数据库表A:

aid | data
---------

Database table B:

bid | data
---------

Database table AB:

aid | bid
----------

Class A{
    private long aid;
    private String data;
    private Set<B> bSet;
}

Class B{
    private long bid;
    private String data;
    private Set<A> aSet;
}


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name='test.A' table='A'>
        <id name='aid' type='long' column='aid'>
        </id>
        <set name="bSet" table="AB"
            inverse="false" fetch="select" cascade="save-update">
            <key>
                <column name="aid" not-null="true" />
            </key>
            <many-to-many entity-name="test.B">
                <column name="bid" not-null="true" />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name='test.B' table='B'>
        <id name='bid' type='long' column='bid'>
        </id>
        <set name="aSet" table="AB"
            inverse="false" fetch="select" cascade="save-update">
            <key>
                <column name="bid" not-null="true" />
            </key>
            <many-to-many entity-name="test.A">
                <column name="aid" not-null="true" />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>
表B

bid | data
-----------
1   | [json data b1]
--------------------
2   | [json data b2]
表AB

aid | bid
----------
1   | 1
----------
1   | 2
----------
2   | 1
----------
现在,当我想更新A(比如Id为1)时,我只填充了A.data(UI只发送相关数据) 对于A.它不知道关于A-B映射的任何信息),A.bSet为null或为空。 当我保存这个时,它会删除映射表的条目

String aJson = "{aid:1, data:['newJsonData']}";
A a = JsonParser.parse(aJson);
session.saveOrUpdate(a);
表AB变为

aid | bid
----------
2   | 1
----------
有没有办法避免此删除?

使用
merge()
而不是
saveOrUpdate()
,并确保合并时不会将集合重置为空集合:

String aJson = "{aid:1, data:['newJsonData']}";
A detachedA = JsonParser.parse(aJson);
A existingA = (A) session.get(A.class, detachedA.getId());
Set<B> bs = existingA.getBs(); // save the Bs to restore them afterwards
session.merge(detachedA);
existingA.setBs(bs); // restore the Bs
String aJson=“{aid:1,数据:['newJsonData']}”;
A detachedA=JsonParser.parse(aJson);
A existingA=(A)session.get(A.class,detachedA.getId());
设置bs=existingA.getBs();//保存Bs以在以后恢复它们
合并(detachedA);
现有的挫折(bs);//恢复Bs

感谢您的快速回复。这是代码。谢谢,在合并之前在existingA中设置setB后,这项功能非常有效。我在想,如果有什么办法可以避免额外的数据库调用来获取existingA,因为我不想在seta中做任何更改,你的意思是在合并之前在detachedA中设置setB,对吗?因为在合并之前,setB已经存在于existingA中。无法避免附加select子句。
String aJson = "{aid:1, data:['newJsonData']}";
A detachedA = JsonParser.parse(aJson);
A existingA = (A) session.get(A.class, detachedA.getId());
Set<B> bs = existingA.getBs(); // save the Bs to restore them afterwards
session.merge(detachedA);
existingA.setBs(bs); // restore the Bs