Hibernate双向父/子问题

时间:2009-07-09 13:58:49

标签: java hibernate

我在使用hibernate 3实现双向父/子关系时遇到问题。在这种情况下,父类是ReportCriteria类。这个孩子属于PkVisit班。我已经粘贴了我的hibernate配置文件以及下面的底层java对象。

ReportCriteria配置:

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

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

    <bag name="pkVisits" table="masterPkWeeks" cascade="all-delete-orphan" inverse="true">
        <key column="runId"/>
        <one-to-many class="PkVisit"/>
    </bag>
</class>
</hibernate-mapping>

ReportCriteria bean:

public class ReportCriteriaBean {

private Integer id;

private List<PkVisit> pkVisits =  LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(PkVisit.class));

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

public List<PkVisit> getPkVisits() {
    return pkVisits;
}

public void setPkVisits(List<PkVisit> pkVisits) {
    this.pkVisits = pkVisits;
}

}

PkVisit配置:

<hibernate-mapping package="org.fstrf.masterpk.domain">
<class name="PkVisit" table="masterPkWeeks">
    <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="week" column="week" />

</class>
</hibernate-mapping>

PkVisit Bean:

public class PkVisit {
private Integer id;

private ReportCriteriaBean reportCriteriaBean;

private Integer week;

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 Integer getWeek() {
    return week;
}
public void setWeek(Integer week) {
    this.week = week;
}
}

当我尝试保存ReportCriteria的实例时会出现问题,由于级联也应该保存任何子PkVisits。但是,使用

调用保存时
hibernateTemplate.saveOrUpdate(reportCriteria);

生成以下错误:

org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: org.fstrf.masterpk.domain.PkVisit.reportCriteriaBean; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: org.fstrf.masterpk.domain.PkVisit.reportCriteriaBean

当我保存不包含PkVisits的报告条件时,一切都按预期工作,但只要任何元素都在ReportCriteria bean的pkVisits列表中,就会发生错误。

解决方案编辑:

我的问题是我从未在子代(PkVisits)中明确设置父(ReportCriteriaBean)。我通过以下方式编辑我的PkVisits setter来解决问题:

public void setPkVisits(List<PkVisit> pkVisits) {
    this.pkVisits = pkVisits;
    for(PkVisit visit : pkVisits){
        visit.setReportCriteriaBean(this);
    }
}

2 个答案:

答案 0 :(得分:2)

您似乎没有正确地在java中创建双向链接。我建议在ReportCriteriaBean上创建一个add方法;事情的影响:

public boolean add(PkVisit pkVisit) {
   boolean added = false;
   added = getPkVisits().add(pkVisit);
   if (added) {
       pkVisit.setReportCriteriaBean(this);
   }
   return added;
}

该错误表示如果其ReportCriteriaBean为null,则无法保存PkVisit。我认为上面的代码是你缺失的链接。如果你走这条路线,你只需要在保持报告标准之前将PkVisit添加到ReportCriteriaBean,并且一切都应该很好。

此外,这里有关于此主题的hibernate文档的链接section 21.2

答案 1 :(得分:0)

在saveOrUpdate()调用之前检查PkVisit是否生成正常。

然后,你可能需要在你没有hibernate会话的地方访问它们之前急切获取你拥有hibernate会话的reportCriteriaBean / pkVisits:

Hibernate.initialize(reportCriteriaBean.getPkVisits());