微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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个属性.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐