我们使用 JPA 2.0 和 EclipseLink 作为我们的 ORM 提供者。数据库是oracle 11g。
在我们的数据模型中,我们有两个实体,如下所示,由单向 @OneToMany 关系映射。
@Entity
@Table(name = "v_page")
public class Page {
@Id
@GeneratedValue(generator = "g_page")
@SequenceGenerator(name = "g_page", sequenceName = "sq_page")
private long id;
@Column(name = "navigation_id")
private String navigationId;
@Column
private String title;
@OneToMany(cascade = ALL, fetch = EAGER)
@JoinColumn(name = "page_id")
@OrderColumn(name = "position")
private List<Section> sections = new ArrayList<>();
}
第二个实体,部分:
@Entity
@Table(name = "v_section")
public class Section {
@Id
@GeneratedValue(generator = "g_section")
@SequenceGenerator(name = "g_section", sequenceName = "sq_section")
private long id;
@Column
private String title;
@Column
@Lob
private String content;
}
创建带有部分的页面并将它们插入数据库可以正常工作。唯一的问题是 EclipseLink 为每个插入部分生成两个 SQL 语句。
INSERT INTO v_page (ID, navigation_id, TITLE, manual_id) VALUES (?, ?, ?, ?)
INSERT INTO v_section (ID, CONTENT, TITLE) VALUES (?, ?, ?)
INSERT INTO v_section (ID, CONTENT, TITLE) VALUES (?, ?, ?)
UPDATE v_section SET position = ?, page_id = ? WHERE (ID = ?)
UPDATE v_section SET position = ?, page_id = ? WHERE (ID = ?)
这可以防止我们在 page_id 和 position 列上设置非空约束。
我不明白为什么 EclipseLink 不应该能够将插入和更新组合到单个插入中,因为此时已经创建了拥有实体页面。我们可以做些什么来让 EclipseLink 只生成单个插入?