我有一个“有趣”的实体结构,但我一直在尝试克隆它们。我基本上有一个我正在克隆的超级父母。让我们称这个类为 Document
。一个文档至少有一个 Function
和一个 Component
。现在这部分不是问题,它们是 @OneToMany
和 @ManyToOne
,我可以很好地克隆它们。但是现在有第三个类同时属于 Function
和 Component
- 我们称之为 Interaction
。按照设计,这是 Function
和 Component
的一部分,因为它描述了两者在交互时所做的事情。
现在在正常流程中会有一个创建顺序,首先创建一个 Document
,然后自动创建至少一个 Component
和 Function
。之后可以创建 Interactions
。您可以将其想象成一个矩阵,其中 Interaction
描述了一个 Component
如何与一个 Function
交互。一般而言,Component
和 Function
不相关,可以独立存在,但至少每个中的一个将始终存在,因此矩阵存在。
现在的问题是克隆整个文档。克隆所有嵌套实体时,必须克隆并保持它们的关系。但是,在克隆时不知道 ID(因为它们必须取消设置或创建新实体),所以我不确定如何在此处防止重复。
如何克隆整个 Document
及其与新 ID 的子关系并保持所有关系完好无损?我知道如果所有关系都处于“线性”结构中,这很容易,但多个父级似乎很困难。
为了清楚起见,这是一张图表:
Document.java
@Table(name = "document")
@Entity
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy = "document", cascade = CascadeType.ALL)
private List<Component> components = new ArrayList<>();
@OneToMany(mappedBy = "document", cascade = CascadeType.ALL)
private List<Function> functions = new ArrayList<>();
}
Component.java
@Table(name = "component")
@Entity
public class Component {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
private Document document;
@OneToMany(mappedBy = "component", cascade = CascadeType.ALL)
private List<Interaction> interactions;
}
Function.java
@Table(name = "function")
@Entity
public class Function {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
private Document document;
@OneToMany(mappedBy = "function", cascade = CascadeType.ALL)
private List<Interaction> interactions;
}
Interaction.java
@Table(name = "interaction")
@Entity
public class Interaction {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
private Function function;
@ManyToOne
private Component component;
}
答案 0 :(得分:0)
对于复制图形,通常必须构建从源到目标的身份映射,并在复制之前进行查询。像这样:
interface CustomClonable {
Object clone(Map<Object, Object> mapping);
}
public static <T extends CustomClonable> T clone(T original, Map<Object, Object> mapping) {
Object copy = mapping.get(original);
if (copy == null) {
copy = original.clone(mapping);
mapping.put(original, copy);
}
return (T) copy;
}
您的所有类型都实现该接口并克隆自己,为嵌套对象调用静态克隆方法。