【问题标题】:JPA - Wrong table createdJPA - 创建了错误的表
【发布时间】:2011-08-04 16:35:02
【问题描述】:

鉴于这些实体:

class SportTeam {
   @Id
   @GeneratedValue
   long id;
   @OneToMany
   private Set<PLayer> players;
   @OneToMany
   private Set<Player> stars;
}
// A sport team can have multiple players and some of those players can be stars.

class Player {
   @Id
   @GeneratedValue
   long id;
   (...)
}

这是 Hibernate 生成的 DDL:

CREATE TABLE sportteam
(
  id bigint NOT NULL,
  (...)
  CONSTRAINT sportteam_pkey PRIMARY KEY (id)
)

CREATE TABLE sportteam_player
(
  sportteam_id bigint NOT NULL,
  player_id bigint NOT NULL,
  star_id bigint NOT NULL,
  CONSTRAINT sportteam_player_pkey PRIMARY KEY (sportteam_id, star_id),
  CONSTRAINT fk6cf55c6645d973bc FOREIGN KEY (player_id)
  REFERENCES player (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk6cf55c66ca1af8b8 FOREIGN KEY (star_id)
  REFERENCES player (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT sportteam_player_star_id_key UNIQUE (star_id),
  CONSTRAINT sportteam_player_player_id_key UNIQUE (player_id)
)    


CREATE TABLE player
(
   id bigint NOT NULL,
   (...)
   CONSTRAINT player_pkey PRIMARY KEY (id)
)

我希望 sportteam_player 看起来像这样:

CREATE TABLE sportteam_player
(
  sportteam_id bigint NOT NULL,
  player_id bigint NOT NULL,
  is_star boolean DEFAULT 'FALSE',
  CONSTRAINT sportteam_player_pkey PRIMARY KEY (sportteam_id, player_id),
  CONSTRAINT fk6cf55c6645d973bc FOREIGN KEY (player_id)
  REFERENCES player (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk6cf55c66ca1af8b8 FOREIGN KEY (sportteam_id)
  REFERENCES sportteam (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION
)    

我该怎么办?

【问题讨论】:

  • 你打算在球员集中复制明星球员吗?
  • 是的。同一个 Player 类可以在两个集合中(作为玩家和作为明星)。
  • 我发现这个链接可能对你有帮助:sieze.wordpress.com/2009/09/04/…
  • @Jeremy Tks 给你的链接,非常有趣!

标签: java hibernate postgresql jpa


【解决方案1】:

这样建模 JPA 关系是不可行的。您假设 Team-to-Star 是关系数据库意义上的一对多关系。这当然是某种刻板印象的关系,但它是基于球员是否是明星的属性。所以:

class Player {
  @Id
  @GeneratedValue
  long id;
  @Column(name = “is_star”, columnDefinition="boolean default false")
  boolean star;
  (...)
}

class SportTeam {
  @Id
  @GeneratedValue
  long id;
  @OneToMany
  private Set<PLayer> players;

  public Collection<Player> getStars() {
    // return your stars here, filter through players.
    // if you want you can do caching, but remember to set the field to @Transient
    // so that Hibernate does not think, it could be a relation
  }
}

我为什么要这样做?无论如何,在 SportTeam 中,您已经加载了所有球员。没有理由通过数据库来做到这一点。成为明星是明星的属性,如果您需要 SportTeam 类中的列表,这只是对现有球员的不同看法。

【讨论】:

  • 也可以创建一个类sportteam_player 来映射连接表。
猜你喜欢
  • 2017-09-02
  • 2016-02-15
  • 2019-01-08
  • 1970-01-01
  • 2013-07-18
  • 2013-04-19
  • 1970-01-01
  • 2020-07-23
  • 2015-04-20
相关资源
最近更新 更多