映射JPA实体

时间:2015-01-23 10:58:51

标签: java hibernate jpa

我有很多桌子

programme       episode         performer       prog_ep_perf
----------      ---------       ---------       ------------
programmeId     episodeId       performerId     programmeId
progTitle       episodeTitle    performerName   episodeId
                programmeId                     performerId

prog_ep_perf是一个连接表(由于连接表,剧集表中的programmeId可能是多余的?)。我已经找到了以下关系,我认为这是正确的

programme
  @OneToMany
  episode     --> One programme can have many episodes
  @OneToMany
  performers  --> One programme can have many performers

episode
  @OneToOne
  programme  --> One episode links to one programme
  @OneToMany
  performers --> One episode can have many performers

performer
  @OneToMany
  programme  --> One performer can have many programmes
  @OneToMany
  episode    --> One performer can have many episodes

以下是我如何设置实体,这是正确的吗?

@Entity
@Table(name = "PROGRAMME")
public class Programme {

  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy="increment")
  private Long programmeId;

  private String progTitle;

  @OneToMany(      
      targetEntity=Performer.class,
      cascade={CascadeType.PERSIST, CascadeType.MERGE}
  )
  @JoinTable(
      name="PROG_EP_PERF",
      joinColumns=@JoinColumn(name="PROGRAMMEID"),
      inverseJoinColumns={@JoinColumn(name="PERFORMERID")}
  )
  private Set<Performer> performers;

  @OneToMany(      
      targetEntity=Performer.class,
      cascade={CascadeType.PERSIST, CascadeType.MERGE}
  )
  @JoinTable(
      name="PROG_EP_PERF",
      joinColumns=@JoinColumn(name="PROGRAMMEID"),
      inverseJoinColumns={@JoinColumn(name="EPISODEID")}
  )
  private Set<Episode> episodes;
}

@Entity
@Immutable
@Table(name = "EPISODE")
public class Episode {

  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy="increment")
  private Long episodeId;

  @Type(type="com.springtests.model.Programme")
  @OneToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
  @JoinColumn(name="PROGRAMMEID")
  private Programme programme;

  private String episodeTitle;

  @OneToMany(      
      targetEntity=Performer.class,
      cascade={CascadeType.PERSIST, CascadeType.MERGE}
  )
  @JoinTable(
      name="PROG_EP_PERF",
      joinColumns=@JoinColumn(name="EPISODEID"),
      inverseJoinColumns={@JoinColumn(name="PERFORMERID")}
  )
  private Set<Performer> performers;

}

@Entity
@Immutable
@Table(name = "PERFORMER")
public class Performer {

  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy="increment")
  private Long performerId;      

  private String performerName;

  @OneToMany(      
      cascade = {CascadeType.PERSIST, CascadeType.MERGE},
      targetEntity = Programme.class
  )
  @JoinTable(
      name="PROG_EP_PERF",
      joinColumns=@JoinColumn(name="PERFORMERID"),
      inverseJoinColumns={@JoinColumn(name="PROGRAMMEID")}
  )
  public Set<Programme> programmes;

  @OneToMany(      
      cascade = {CascadeType.PERSIST, CascadeType.MERGE},
      targetEntity = Programme.class
  )
  @JoinTable(
      name="PROG_EP_PERF",
      joinColumns=@JoinColumn(name="PERFORMERID"),
      inverseJoinColumns={@JoinColumn(name="EPISODEID")}
  )
  public Set<Episode> episodes;

}

1 个答案:

答案 0 :(得分:1)

如果表是固定的,你只需要实体来表示数据库中的内容,那么看起来程序有一个OneToMany到剧集,并且剧集有一个ManyToOne回到程序使用episode.programmeId字段作为外键:

public class Programme {
  ..
  @OneToMany(mappedby="programme")
  private Set<Episode> episodes;
  ..

public class Episode {
  ..
  @ManyToOne
  @JoinColumn(name = "programmeId")
  private Programme programme;
  ..

由于Episode.programme关系控制数据库中的外键,如果您想要实际添加Programme.episodes集合,则由您决定。如果这样做,您必须自己维护它以在进行更改时保持双方同步。即如果您将剧集添加到集合中,JPA将不会自动修复节目参考,当您指向剧集时,它也不会将剧集添加到节目的集合中。

对于prog_ep_perf表,这是一种可能难以处理的3路映射。如果要为每一行填充所有3个外键,则无法按照您布局的方式进行映射,因为通过将其分成多个1:M映射,一个外键将始终为null。

相反,最佳解决方案是将prog_ep_perf表映射为实体,以便您可以在应用程序中完全按照您的需要或需要处理它。另一种方法是使用Map作为具有ManyToMany关系的集合类型。看到 http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Mapping_a_Join_Table_with_Additional_Columns有关其他信息(JPA 1.0)和JPA 2.0,请参阅https://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/MapKeyColumnshttp://docs.oracle.com/javaee/6/api/javax/persistence/MapKeyJoinColumn.html,但它可能如下所示:

public class Programme {
  ..
  @ManyToMany
  @JoinTable(name="prog_ep_perf",
                   joinColumns=@JoinColumn(name="episodeId"),
                   inverseJoinColumns=@JoinColumn(name="programmeId"))
  @MapKeyJoinColumn(name="performerId")
  Map<Performer, Episode> prog_ep_perf;
  ..
}