У меня есть следующая модель:
Отчет , ReportSection и ReportSectionProperty .
Отчет имеет ноль ко многим ReportSections , ReportSection имеет ноль ко многим ReportSectionPropert -ies.Это будет квалифицироваться как трехуровневый граф объектов.
Я создаю новый Отчет , затем добавляю к нему несколько разделов и добавляю к нему некоторые свойства.Когда я пытаюсь сохранить 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, но очевидно, что объект не сохраняется при сохранении ReportSection.
Если я добавлю em.persist (report), то em.flush () между каждой операциейдобавляя разделы или свойства, все работает.Так ли это?
Если я не добавляю какие-либо свойства в разделы, постоянный Отчет работает даже без em.flush ().
Я использую OpenJPA 2.0.3 в качестве JPAПоставщик.
Может быть, некоторые соответствующие части кода:
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
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;
}
}