我们得到了这样的设置:一个文档有一个元素列表,这些元素是 Element 的子类,在这个例子中是 Link。链接与资源具有@OneToOne 关系。只要我们一步创建整个对象图,一切都会奏效。
我们现在更改了代码以创建 Resource 实例,将其持久化并将其传递给我们的客户端(Web,序列化为 JSON 的对象)。客户端创建 Document 的实例并添加与现有资源的链接。之后,我们尝试持久化新文档。
此时操作失败,因为 JPA 尝试使用相同的 id 持久化已经存在的 Resource。我认为发生这种情况是因为 Resource 已分离,JPA 无法确定该实体是否必须合并或持久化。当我删除 CascadeType.ALL 并用 CascadeType.MERGE 替换它时,一切都很好,除了资源根本没有更新。
基本上工作流程如下:
- 创建和持久化资源
- 离开交易
- 开始交易
- 使用链接和(分离的)资源创建文档
- 错误
我们的 JPA 配置是否存在问题(查看我们的实体)?如果你能给我一个提示,我很想给你一杯啤酒……:-) TYIA。
我们的设置是:EclipseLink 2.4.1、Spring Data JPA 1.3.0(使用@Repository)和 PostgreSQL 9.2。
文档:
@Entity
public class Document implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@OrderColumn
@JoinColumn(name = "document_id")
private List<Element> elements = new ArrayList<Element>();
// getters and setters
}
元素:
@Entity
@Inheritance(strategy = InheritanceType.
public class Element implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document_id", insertable = false, updatable = false)
private Document document;
// getters and setters
}
关联:
@Entity
public class Link extends Element {
@Column
private String appearance;
@Column
private String referenceType;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Resource resource;
// getters and setters
}
资源:
@Entity
public class Resource {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column
private String uri;
// getters and setters
}