Eclipselink 2.5.1-RC1 JPA 3-Way ManyToMany:结点 table 记录的自动 addition/removal
Eclipselink 2.5.1-RC1 JPA 3-Way ManyToMany: Automatic addition/removal of junction table records
我有 3 个实体:X、Y、Z。X 由 Y 的集合组成,Y 将每个 Y 与 Z 相关联。(Y-Z) -> X 关联在 junction/link [=43 中维护=] 使用三个引用作为复合主键调用 YZ_2_X_Map:YId、ZId、XId。
以下是 X 实体的代码:
@Entity
public class X implements Serializable {
// Properties
//bi-directional many-to-one association to YZ_2_X_Map
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
@JoinTable(name="YZ_2_X_Map",
joinColumns=
@JoinColumn(name="XId")
)
private List<YZ_2_X_Map> yZList;
public void setYZList(List<YZ_2_X_Map> yZList) {
this.yZList = yZList;
}
}
以下是 YZ_2_X_Map 实体的代码:
public class YZ_2_X_Map implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private YZ_2_X_MapPK id;
//bi-directional many-to-one association to Y
@ManyToOne
@JoinColumn(name="YId")
private Y y;
//bi-directional many-to-one association to Z
@ManyToOne
@JoinColumn(name="ZId")
private Z z;
//bi-directional many-to-one association to X
@ManyToOne
@JoinColumn(name="XId")
private X x;
// Methods
}
我的期望是,每当我坚持 X 时,根据 yZList 中的条目,YZ_2_X_Map 连接点 table 中的记录应该是 inserted/deleted。
使用上面的代码,向 yzList 添加新条目会按照我的预期在 YZ_2_X_Map table 中添加新记录。
但是,从 yzList 中删除条目不会从 YZ_2_X_Map table 中删除相应的记录。
我还尝试从 class X 中的 @OneToMany 注释中删除 mappedBy,并从 class YZ_2_X_Map 中删除 x 属性。在这种情况下,虽然从 yzList 中删除条目会删除相应的记录,但将新条目添加到 yzList 并持久化 X 会生成 INSERT into YZ_2_X_Map 但会抛出重复条目异常。
请告诉我如何根据 yZList 中的条目在 YZ_2_X_Map table 中实现自动 addition/removal 记录的期望。
您为 YZ_2_X_Map table 创建了一个实体,但随后创建了一个 1:m 映射到使用 YZ_2_X_Map 连接 table - 实际上是一个连接 table 到一个连接 table。 mappedBy="x" 告诉映射要使用的外键包含在 YZ_2_X_Map.x 映射中。 Join table 或 join 列仅在这是关系的拥有方或单向时才需要。
只需要:
public class X implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
private List<YZ_2_X_Map> yZList;
...
如果您希望 JPA 运行以便从 yZList 中删除一个实体会导致 YZ_2_X_Map 实体和行被删除,那么您需要将关系标记为私有(特定于 EclipseLink)或者如果使用 JPA 2.0,则 orphanRemoval=true。这将强制 JPA 在实体从映射中取消引用时也将其删除。
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true, mappedBy="x")
或
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
@PrivateOwned
private List<YZ_2_X_Map> yZList;
我有 3 个实体:X、Y、Z。X 由 Y 的集合组成,Y 将每个 Y 与 Z 相关联。(Y-Z) -> X 关联在 junction/link [=43 中维护=] 使用三个引用作为复合主键调用 YZ_2_X_Map:YId、ZId、XId。
以下是 X 实体的代码:
@Entity
public class X implements Serializable {
// Properties
//bi-directional many-to-one association to YZ_2_X_Map
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
@JoinTable(name="YZ_2_X_Map",
joinColumns=
@JoinColumn(name="XId")
)
private List<YZ_2_X_Map> yZList;
public void setYZList(List<YZ_2_X_Map> yZList) {
this.yZList = yZList;
}
}
以下是 YZ_2_X_Map 实体的代码:
public class YZ_2_X_Map implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private YZ_2_X_MapPK id;
//bi-directional many-to-one association to Y
@ManyToOne
@JoinColumn(name="YId")
private Y y;
//bi-directional many-to-one association to Z
@ManyToOne
@JoinColumn(name="ZId")
private Z z;
//bi-directional many-to-one association to X
@ManyToOne
@JoinColumn(name="XId")
private X x;
// Methods
}
我的期望是,每当我坚持 X 时,根据 yZList 中的条目,YZ_2_X_Map 连接点 table 中的记录应该是 inserted/deleted。
使用上面的代码,向 yzList 添加新条目会按照我的预期在 YZ_2_X_Map table 中添加新记录。
但是,从 yzList 中删除条目不会从 YZ_2_X_Map table 中删除相应的记录。
我还尝试从 class X 中的 @OneToMany 注释中删除 mappedBy,并从 class YZ_2_X_Map 中删除 x 属性。在这种情况下,虽然从 yzList 中删除条目会删除相应的记录,但将新条目添加到 yzList 并持久化 X 会生成 INSERT into YZ_2_X_Map 但会抛出重复条目异常。
请告诉我如何根据 yZList 中的条目在 YZ_2_X_Map table 中实现自动 addition/removal 记录的期望。
您为 YZ_2_X_Map table 创建了一个实体,但随后创建了一个 1:m 映射到使用 YZ_2_X_Map 连接 table - 实际上是一个连接 table 到一个连接 table。 mappedBy="x" 告诉映射要使用的外键包含在 YZ_2_X_Map.x 映射中。 Join table 或 join 列仅在这是关系的拥有方或单向时才需要。
只需要:
public class X implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
private List<YZ_2_X_Map> yZList;
...
如果您希望 JPA 运行以便从 yZList 中删除一个实体会导致 YZ_2_X_Map 实体和行被删除,那么您需要将关系标记为私有(特定于 EclipseLink)或者如果使用 JPA 2.0,则 orphanRemoval=true。这将强制 JPA 在实体从映射中取消引用时也将其删除。
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true, mappedBy="x")
或
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="x")
@PrivateOwned
private List<YZ_2_X_Map> yZList;