Eclipselink 2.5.1-RC1 JPA 3-Way ManyToMany:自动添加/删除联结表记录

时间:2015-01-15 15:14:39

标签: jpa many-to-many eclipselink

我有3个实体:X,Y,Z.X由Ys的集合组成,Ys将每个Y与Z相关联。(Y-Z) - > X关联在名为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联结表中的记录。

使用上面的代码,向yzList添加新条目会根据我的期望在YZ_2_X_Map表中添加新记录。

但是,从yzList中删除条目不会从YZ_2_X_Map表中删除相应的记录。

我还尝试从类X中的@OneToMany注释中删除mappedBy,并从类YZ_2_X_Map中删除x属性。在这种情况下,从yzList中删除条目会删除相应的记录,向yzList添加新条目并持久化X会生成INSERT到YZ_2_X_Map但会抛出重复条目异常。

请告诉我如何根据yZList中的条目实现我在YZ_2_X_Map表中自动添加/删除记录的期望。

1 个答案:

答案 0 :(得分:2)

您为YZ_2_X_Map表创建了一个实体,但随后创建了一个1:m映射到使用YZ_2_X_Map连接表的实体 - 实际上是连接表的连接表。 mappedBy =&#34; x&#34;告诉映射要使用的外键包含在YZ_2_X_Map.x映射中。只有当这是关系的拥有方或者它是单向的时,才需要连接表或连接列。

所需要的只是:

  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;