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.
精彩评论