java - 在没有 em.flush() 的情况下使用 JPA 持久化深度对象图

标签 java orm jpa openjpa

我有以下模型:

报告ReportSectionReportSectionProperty

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

我创建了新的报表,然后向其中添加了一些部分,然后向其中添加了一些属性。当我尝试坚持报告时,出现以下错误:

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);
        }
    }
}

ReportSection.java

public class ReportSection{

    @ManyToOne
    @JoinColumn(name="id_node")
    private Report report;

    @OneToMany(targetEntity=ReportSectionProperty.class, cascade=CascadeType.ALL,   mappedBy="reportSection")
    private List reportSectionProperties;

    public void setReport(Report report) {
        this.report = report;
    }

    public void addReportSectionProperty(ReportSectionProperty reportSectionProperty){
        synchronized (this) {
            if (getReportSectionProperties() == null)
                reportSectionProperties = new ArrayList();
            reportSectionProperties.add(reportSectionProperty);
            reportSectionProperty.setReportSection(this);
        }
    }
}

ReportSectionProperty

public class ReportSectionProperty{

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id_report_section")
    private ReportSection reportSection;

    public void setReportSection(ReportSection reportSection) {
        this.reportSection = reportSection;
    }
}

最佳答案

这可能是一个死线程,但由于我遇到了类似的问题,我想展示我是如何设法解决它的,以供将来引用(以防万一失去灵魂必须处理 OpenJPA)

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

property name="openjpa.jdbc.SchemaFactory"value="native(ForeignKeys=true)"

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

关于java - 在没有 em.flush() 的情况下使用 JPA 持久化深度对象图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3717887/

相关文章:

hibernate - EntityManager (setHint) Read-Only 和 Session Read-Only 有什么区别?

java - 为 appengine 的数据存储区编写基本查询

Java 音频流(mp3spi lib),UnsupportedAudioFileException

java - Android 应用程序强制关闭,没有显示任何错误

.net - 如何为 .net 选择对象关系映射

java - JPA 查询 - 如何获得特定的结果集?

jpa - 为当前日期创建查询匹配

调用 HttpUrlConnection.connect() 时出现 javax.net.ssl.SSLProtocolException

python - Django 1.11 - 嵌套的 OuterRef 用法

django - 如何更新已注释的查询集?