java – 在JPA / Hibernate中建立两对多的关系

我有以下实体关系问题. “游戏”必须有两个(只有两个)“团队”对象. “团队”可以有很多“游戏”

据我所见,这是一种两对多的关系.但是,我不知道如何在JPA中建模.例如,我要做这样的事情

@Entity
public class Team extends BaSEObject {
  private Long id;
  private Set<Game> games;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO) 
  public Long getId() {return id;}
  public void setId(Long id) {this.id = id;}

  @OnetoMany(mappedBy = "game")
  public Set<Game> getGames() {return games;}
  public void setGames(Set<Game> games) {this.games = games;}
}

@Entity
public class Game extends BaSEObject {
  private Long id;
  private Team team1;
  private Team team2;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO) 
  public Long getId() {return id;}
  public void setId(Long id) {this.id = id;}

  @ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE?
  public Team getTeam1() {return team1;}
  public void setTeam1(Team team1) {this.team1 = team1;}

  @ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE?
  public Team getTeam2() {return team2;}
  public void setTeam2(Team team1) {this.team2 = team2;}
}

但是,如您所见,我不知道如何从注释方面将表连接在一起.有没有人曾经做过这样的事情?任何想法,帮助?

非常感谢!

解决方法

我希望有人想出一个很棒的解决方案,但这是一个棘手的情况,我从来没有找到一种方法映射得很好.您的选择包括

>改变你建立关系的方式.例如,你可以这样做:

@Entity
public class GameMembership {
   Team team;
   Game game;
   int gamePosition; // If tracking Team 1 vs Team 2 matters to you
}

然后游戏有一个集合< GameMembership>,即您将它建模为多对多.游戏仍然可以有方便的方法来设置Team 1和Team 2等(业务逻辑强制只有2个团队,但是已经完成),但是他们映射回到Hibernate使用的集合.
放弃关系是双向的 – 选择一个方向(游戏→团队似乎最合适),只打动这种关系.查找一个团队参与的游戏随后成为您的DAO等操作,而不是团队本身可以访问的操作:

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端使用mappedBy来表示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个属性.

相关文章

前言 逆向工程从数据库表直接生成代码,是日常开发中常用的敏...
前言 Java网络编程之Socket套接字,Socket套接字使用TCP提供...
前言 虽然现在已经很少项目会涉及GUI技术,但作为一个合格的...
前言 几乎所有的系统都有密码安全要求,这是基础的安全策略,...
前言 当我们在写设计文档,或者是其他涉及到数据架构、表结构...
前言 Fiddler是一款强大的Web调试代理工具,又称抓包软件,本...