我希望有人能提出一个很棒的解决方案,但是这是一个棘手的情况,我从未能找到一种很好的映射方法。您的选择包括:
- 更改关系建模的方式。例如,您可能会遇到以下情况:
@Entity
public class GameMembership {
Team team;
Game game;
int gamePosition; // If tracking Team 1 vs Team 2 matters to you
}
然后
Game有一个
Collection<GameMembership>,即您将其建模为多对多。
Game仍然可以使用方便的方法来设置团队1和团队2,等等(业务逻辑来强制只有2个团队,但是已经完成了),但是它们映射回
Collection了Hibernate所使用的。
- 放弃建立双向关系-选择一个方向(
Game
→Team
似乎最合适),然后仅打na该关系。找到所涉及的Games
aTeam
然后就可以从您的DAO等中进行操作,而不是从其Team
本身可以访问的内容中进行操作:public class GameDAO {....public Collection<Game> gamesForTeam(Team t) { .... Query q = session.createQuery("FROM Game WHERe team1 = :team OR team2 = :team"); q.setParameter("team", t); return q.list();}}
或类似的东西
- 继续沿您所走的路线行驶,但最后会“作弊”
Team
。Game
侧面的属性应映射为正常的多对一关系;然后mappedBy
在Team
末尾用来表示Game
“控制”关系。public class Team { ... @oneToMany(mappedBy="team1") private Set<Game> team1Games; @oneToMany(mappedBy="team2") private Set<Game> team2Games;
并 再 有一个简便属性为您的API(
team1Games和
team2Games只是对Hibernate的使用):
@Transient public Set<Game> getGames() { Set<Game> allGames = new HashSet<Game>(team1Games); allGames.addAll(team2Games); // Or use google-collections Sets.union() for bonus points return allGames; }因此对于您的班级的调用者来说,有2个属性是透明的。



