私は次のモデルを持っています:
Report、 ReportSectionおよび ReportSectionProperty。
レポートには0から多数のReportSectionsがあり、ReportSectionには0から多数のReportSectionPropert -iesがあります。これは、3レベルの深さのオブジェクトグラフとしての資格があります。
新しいレポートを作成し、それにいくつかのセクションを追加してから、いくつかのプロパティを追加します。レポートを永続化しようとすると、次のエラーが発生します。
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は確かにレポートテーブルの次のIDですが、明らかに、ReportSectionが保存されているときにそのオブジェクトは保存されません。
セクションまたはプロパティを追加する各操作の間にem.persist(report)、次にem.flush()を配置すると、すべてが機能します。これは行く方法ですか?
セクションにプロパティを追加しない場合、em.flush()がなくても、レポートの永続化は機能します。
私はJPAプロバイダーとしてOpenJPA2.0.3を使用しています。
たぶん、コードのいくつかの関連部分:
Report.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
パブリッククラスReportSection{ @ManyToOne @JoinColumn(name = "id_node") プライベートレポートレポート; @OneToMany(targetEntity = ReportSectionProperty.class、cascade = CascadeType.ALL、mappedBy = "reportSection") プライベートリストreportSectionProperties; public void setReport(レポートレポート){ this.report=レポート; } public void addReportSectionProperty(ReportSectionProperty reportSectionProperty){ 同期(これ){ if(getReportSectionProperties()== null) reportSectionProperties = new ArrayList(); reportSectionProperties.add(reportSectionProperty); reportSectionProperty.setReportSection(this); } } }
ReportSectionProperty
パブリッククラスReportSectionProperty{ @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "id_report_section") プライベートReportSectionreportSection; public void setReportSection(ReportSection reportSection){ this.reportSection = reportSection; } }