【问题标题】:Hibernate bidirectional parent/child problemHibernate双向父/子问题
【发布时间】:2009-07-09 13:58:48
【问题描述】:

我在使用休眠 3 实现双向父/子关系时遇到问题。在本例中,父级属于 ReportCriteria 类。孩子属于 PkVisit 类。我已经粘贴了我的休眠配置文件以及下面的底层 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 设置器解决了这个问题:

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

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    您似乎没有在 java 中正确创建双向链接。我建议在 ReportCriteriaBean 上创建一个 add 方法;大意是:

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

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

    另外,这里是关于这个主题的休眠文档的链接,section 21.2

    【讨论】:

    • 您说 ReportCriteriaBean 为空是正确的,但由于设置 PkVisits 列表的方式,此添加功能本身不起作用。我已经编辑了我的原始帖子,以表明我所做的确切更改。谢谢!
    【解决方案2】:

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

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

    Hibernate.initialize(reportCriteriaBean.getPkVisits());
    

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2010-11-15
      • 2019-07-09
      • 2016-04-19
      相关资源
      最近更新 更多