我要添加一个包含其他数据的交叉表,并使用@EmbeddedId为受此表中的记录绑定的实体(entity1和entity2)制作一个复杂的ID。
保存实体1时,我想通过级联保存所有数据。因此,这就是为什么在实体1中具有:
@OneToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH},
fetch = FetchType.LAZY, mappedBy = "id.entity1")
private List<Entity1ToEntity2Link> links = new ArrayList<>();
在Entity1ToEntity2Link中,我具有@EmbeddedId,并且在其中具有指向两个实体的链接。但是,我希望在保存实体1时保存第二个。因此,我这样做是这样的:
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private Entity2 entity2;
但是,不幸的是,我在@EmbeddedId内部拥有的级联似乎被忽略了。我可以看到未生成用于插入的sql,并且在保存Entity1ToEntity2Link时出现错误:
违反-找不到父键
我怀疑@EmbeddedId不支持级联。但是,我不确定。您有什么主意,在保存Entity1ToEntity2Link之前如何保存Entity2?
ID对象:
@Embeddable
public class LinkId extends AbstractLinkId {
//...
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
private Entity2 entity2;
//...
}
@MappedSuperclass
public class AbstractLinkId {
//...
@ManyToOne
private Entity1 entity1;
//...
}
最佳答案
而不是使用Entity1ToEntity2Link尝试直接的ManyToMany关系。
public class Entity1 {
@ManyToMany
@JoinTable(
name="LINK_TABLE_NAME",
joinColumns=@JoinColumn(name="ENTITY1_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="ENTITY2_ID", referencedColumnName="ID"))
private List<Entity2> entities2;
}
public class Entity2 {
@ManyToMany(mappedBy="entities2")
private List<Entity1> entities1;
}
您的方法存在以下问题。您尝试在Entity1上调用save,将其级联到Entity1ToEntity2Link。现在Entity1ToEntity2Link需要Entity1作为主键,但是Entity1还不存在。
它们是使用Entity1ToEntity2Link进行保存的两种方法。
首先:不要在保存Entity1之后将层叠添加到Entity1ToEntity2Link并保存链接。
其次:将一个生成的ID添加到Entity1ToEntity2Link。