【问题标题】:Hibernate: update on parent-child relationship causes duplicate childrenHibernate:父子关系的更新导致重复的孩子
【发布时间】:2010-05-06 21:25:32
【问题描述】:

我有一个父子关系,其中父级有一组子级(一组是特定的)。子集合设置为 cascade="all-delete-orphan"。当我最初保存父元素时,一切都按预期工作。但是,当我更新父级并再次保存时,所有子级都被重新保存。

这种行为让我相信父母正在失去对孩子集合的引用,因此在坚持所有孩子时都会重新保存。似乎解决此问题的唯一方法是不使用此子集合的 setter 方法,但不幸的是,此 setter 在我的应用程序中被隐式调用(Spring MVC 用于将多选表单元素绑定到此集合,并且 setter在表单提交时由 spring 调用)。覆盖此设置器以不丢失引用(即,执行 colleciton.clear() 和 collection.addAll(newCollection) 而不是 collection = newCollection)显然是休眠的禁忌,正如这里指出的那样:https://forum.hibernate.org/viewtopic.php?t=956859

有谁知道如何规避这个问题?我在下面发布了一些代码。

父休眠配置:

<hibernate-mapping package="org.fstrf.masterpk.domain">
<class name="ReportCriteriaBean" table="masterPkReportCriteria">

    <id name="id" column="id">
        <generator class="org.hibernate.id.IncrementGenerator" />
    </id>

    <set name="treatmentArms" table="masterPkTreatmentArms" 
         sort="org.fstrf.masterpk.domain.RxCodeComparator" lazy="false" cascade="all-delete-orphan" inverse="true">
        <key column="runid"/>
        <one-to-many class="TreatmentArm"/>
    </set>
</class>
</hibernate-mapping>

父对象:

public class ReportCriteriaBean{

    private Integer id;
    private Set<TreatmentArm> treatmentArms;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    public Set<TreatmentArm> getTreatmentArms() {
        return treatmentArms;
    }
    public void setTreatmentArms(Set<TreatmentArm> treatmentArms) {
        this.treatmentArms = treatmentArms;
        if(this.treatmentArms != null){
        for(TreatmentArm treatmentArm : this.treatmentArms){
            treatmentArm.setReportCriteriaBean(this);
        }
    }
}

子休眠配置:

<hibernate-mapping package="org.fstrf.masterpk.domain">
    <class name="TreatmentArm" table="masterPkTreatmentArms">
        <id name="id" column="id">
            <generator class="org.hibernate.id.IncrementGenerator" />
        </id>

        <many-to-one name="reportCriteriaBean" class="ReportCriteriaBean" column="runId" not-null="true" />

        <property name="rxCode" column="rxCode" not-null="true"/>
    </class>
</hibernate-mapping>

子对象:

public class TreatmentArm {

    private Integer id;
    private ReportCriteriaBean reportCriteriaBean;
    private String rxCode;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public ReportCriteriaBean getReportCriteriaBean() {
        return reportCriteriaBean;
    }
    public void setReportCriteriaBean(ReportCriteriaBean reportCriteriaBean) {
        this.reportCriteriaBean = reportCriteriaBean;
    }
    public String getRxCode() {
        return rxCode;
    }
    public void setRxCode(String rxCode) {
        this.rxCode = rxCode;
    }
}

【问题讨论】:

    标签: hibernate spring-mvc


    【解决方案1】:

    可能来自这个Hibernate Bug

    【讨论】:

    • 在我的场景中,添加一个孩子只执行一次插入,但问题是由于来自 Spring 的 setTreatmentArms() 调用,休眠失去了对一组孩子的引用,因此当坚持它很简单重新插入它们。例如,使用一组子级(CH1、CH2)创建一个新父级。保存后一切正常。但是,如果我随后通过删除 CH2(通过绑定到我的子集合的多选表单对象)来修改此集合并再次保留,那么新的子集现在是 (CH1, CH2, CH1) 它应该只是 (CH1) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多