2

我有以下模型:

报告、 报告和 报告节属性

Report有零到多个ReportSectionsReportSection有零到多个ReportSectionPropert -ies。这将有资格作为三层深度对象图。

我创建新的Report,然后向其中添加一些部分,然后向其中添加一些属性。当我尝试坚持Report时,我收到以下错误:

Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ERROR: insert or update on table "report_section" violates foreign key constraint "fk_report_section_report"
  Detail: Key (id_node)=(186) is not present in table "report". {prepstmnt 20859482 INSERT INTO core.report_section (index_section, name, report_section_type, id_node) VALUES (?, ?, ?, ?) [params=?, ?, ?, ?]} [code=0, state=23503]

所以,OpenJPA 是持久化对象图,但不知何故它是从中间开始的。id_node 186 确实是 Report 表的下一个 id,但是很明显,当 ReportSection 被保存时,该对象没有被保存。

如果我在添加部分或属性的每个操作之间放置 em.persist(report) 然后 em.flush() ,一切正常。这是要走的路吗?

如果我不向部分添加任何属性,则即使没有 em.flush(),持久报告也可以工作。

我使用 OpenJPA 2.0.3 作为 JPA 提供者。


也许代码的一些相关部分:

报告.java

public class Report{

    @OneToMany(targetEntity = ReportSection.class, cascade = CascadeType.ALL, mappedBy="report")
    private List reportSections;

    public void addReportSection(ReportSection section){
        synchronized (this) {
            if (getReportSections() == null)
                reportSections = new ArrayList();
            reportSections.add(section);
            section.setReport(this);
        }
    }
}

报告节.java

公共类 ReportSection{

    @ManyToOne
    @JoinColumn(name="id_node")
    私人报告报告;

    @OneToMany(targetEntity=ReportSectionProperty.class, cascade=CascadeType.ALL, mappedBy="reportSection")
    私有列表报告SectionProperties;

    公共无效集报告(报告报告){
        this.report = 报告;
    }

    公共无效 addReportSectionProperty(ReportSectionProperty reportSectionProperty){
        同步(这个){
            if (getReportSectionProperties() == null)
                reportSectionProperties = new ArrayList();
            reportSectionProperties.add(reportSectionProperty);
            reportSectionProperty.setReportSection(this);
        }
    }
}

报告节属性

公共类 ReportSectionProperty{

    @ManyToOne(级联=CascadeType.ALL)
    @JoinColumn(name="id_report_section")
    私人报告部分报告部分;

    公共无效 setReportSection(ReportSection reportSection) {
        this.reportSection = 报告部分;
    }
}
4

3 回答 3

1

这可能是一个死线程,但是由于我遇到了类似的问题,所以我想展示我是如何设法解决它的,以供将来参考(如果有任何迷失的灵魂必须处理 OpenJPA)

尝试将此属性设置到您的 persistence.xml 中,以便 OpenJPA 可以以正确的顺序重新排列 sql 语句。

属性名称="openjpa.jdbc.SchemaFactory" 值="native(ForeignKeys=true)"

http://openjpa.apache.org/faq.html#FAQ-CanOpenJPAreorderSQLstatementstosatisfydatabaseforeignkeyconstraints%253F

于 2011-03-04T15:51:36.823 回答
0

您是否尝试将 cascade=ALL 添加到从 ReportSection 到 Report 的 @ManyToOne 关系?

在父 Report 对象上发布您的 @Id 属性也可能会有所帮助。

于 2011-11-19T20:40:10.877 回答
0

如果我在添加部分或属性的每个操作之间放置 em.persist(report) 然后 em.flush() ,一切正常。这是要走的路吗?

如果定义了正确的级联设置并正确构建了双向关联(当然不包括任何 JPA 提供程序错误),则不需要这样做。第一部分看起来不错。但我想看看你是怎么做最后一部分的。

于 2010-09-15T17:22:05.447 回答