我有以下型号:
报告的, ReportSection 和 ReportSectionProperty
报告具有零到多个 ReportSections , ReportSection 具有零到多个 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提供程序。
可能是代码的一些相关部分:
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; } }
答案 0 :(得分:1)
这可能是一个死路线,但由于我遇到了类似的问题,我想表明我是如何设法解决它的,以备将来参考(如果任何失去的灵魂必须处理OpenJPA)
尝试将此属性设置为persistence.xml,以便OpenJPA可以按正确的顺序重新排列sql语句。
property name =“openjpa.jdbc.SchemaFactory”value =“native(ForeignKeys = true)”
答案 1 :(得分:0)
如果我在添加部分或属性的每个操作之间放置em.persist(report)和em.flush(),那么一切正常。这是要走的路吗?
在定义适当的级联设置并正确构造双向关联时(当然不包括任何JPA提供程序错误),这不是必需的。第一部分看起来不错。但我想看看你如何做到最后一部分。
答案 2 :(得分:0)
您是否尝试将cascade = ALL添加到从ReportSection到Report的@ManyToOne关系?
将@Id属性也发布在父Report对象上可能会有所帮助。