开发者

JPA - Wrong table created

Given those entities :

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;
   (...)
}

Here is the DDL generated by Hibernate :

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

CREATE TABLE sportteam_player
(
  sporttea开发者_如何学Gom_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)
)

I would prefer the sportteam_player looks like this :

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
)    

How can I do ?


It is not feasible to model JPA relations like that. You assume that Team-to-Star is a one-to-many relation in a relational database sense. It certainly is some kind of a stereotype relation, but it is based on the property of a player that is a star or not. So:

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
  }
}

Why would I do that? In the SportTeam you have loaded all of the Players already anyway. No reason to do that via database. Being a star is a property of the star and if you need the list in the SportTeam class, it is just a different view on the existing players.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜