鉴于这些实体:
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
)
我该怎么办?
答案 0 :(得分:4)
对这样的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课程中的列表,它只是现有玩家的不同观点。