在JPA / Hibernate中建模两对多关系 [英] Modelling a Two to Many Relationship in JPA/Hibernate

查看:119
本文介绍了在JPA / Hibernate中建模两对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体关系问题。一个游戏必须有两个(并且只有两个)团队对象。一个团队可以有很多游戏



就我所见,这是一个两对多的关系。但是......我不知道如何在JPA中对此进行建模。例如,我打算做这样的事情......

  @Entity 
public class Team extends BaseObject {
私人长ID;
私人设置<游戏>游戏;

@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(){返回游戏;}
public void setGames(Set< Game> games){this.games = games;}
}

@Entity
public类游戏扩展BaseObject {
private Long id;
私人团队team1;
私人团队team2;

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

@这是问题 - 我使用何种注释?
public Team getTeam1(){return team1;}
public void setTeam1(Team team1){this.team1 = team1;}

@这是问题 - 注释的含义我用?
public Team getTeam2(){return team2;}
public void setTeam2(Team team1){this.team2 = team2;}
}

但是,正如您所看到的,我不确定如何从注释端将表连接在一起。有没有人曾经做过这样的事情?任何想法,帮助?



非常感谢!

解决方案

会喜欢有人提出一个真棒解决方案,但这是一个棘手的情况,我从来没有能够找到一个很好的映射方式。您的选择包括:


  1. 改变您对关系建模的方式。例如,你可能有这样的东西:

      @Entity 
    公共类GameMembership {
    团队团队;
    游戏游戏;
    int gamePosition; //如果跟踪Team 1 vs Team 2对你很重要

    $ / code>

    然后 Game 有一个集合< GameMembership> ,即你将它建模为多对多。 游戏仍然可以用于设置Team 1和Team 2等方便的方法(业务逻辑强制只有2个团队,但是这样做),但他们映射回Hibernate使用 Collection


  2. 放弃关系是双向的 - 选择一个方向(游戏团队似乎是最合适的)并且只打那个关系。查找游戏 a 团队参与进来,然后成为您的DAO等的操作,而不是可从团队本身:

     公共类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();
    }
    }

    或类似的东西...


  3. 继续沿着您所采用的路线行驶,但在 Team 结尾处欺骗。在 Game 一侧的属性应该被映射为正常的多对一关系;然后在团队末端使用 mappedBy 来指示游戏 '控制'关系。

      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);
    //或者使用google-collections Sets.union()获得奖励积分
    返回allGames;
    }

    所以对于你的类的调用者来说,它有两个属性是透明的。 / p>



I have the following entity relationship problem. A "Game" must have two (and only two) "Team" objects. A "Team" can have many "Games"

This, as far as I can see is a Two-to-Many relationship. However...I don't know how to model this in JPA. Eg, I was going to do something like this...

@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;}
}

But, as you can see, I'm not sure how to link the tables together from an annotation side. Has anyone ever done something like this before? Any ideas, help?

thanks very much!

解决方案

I would love for someone to come up with an awesome solution to this, but it's a tricky situation which I've never been able to find a way to map very well. Your options include:

  1. Change the way you model the relationship. For example, you could have something like:

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

    and then Game has a Collection<GameMembership>, i.e. you model it as many-to-many. Game can still have convenient methods for setting Team 1 and Team 2, etc, (business logic to enforce that there are only 2 Teams, however that's done) but they map back onto the Collection as used by Hibernate.

  2. Give up on having the relationship be bidirectional -- pick one direction (GameTeam seems the most appropriate) and nap only that relationship. Finding the Games a Team is involved in then becomes an operation from your DAO etc, rather than something that's accessible from the Team itself:

    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();
        }
    }
    

    or something similar...

  3. Continue along the route you're taking, but 'cheat' at the Team end. The properties at the Game side should be mapped as normal many-to-one relationships; then used mappedBy at the Team end to indicate that Game 'controls` the relationship.

    public class Team {
            ...
            @OneToMany(mappedBy="team1")
            private Set<Game> team1Games;
            @OneToMany(mappedBy="team2")
            private Set<Game> team2Games;
    

    and then have a convenience property for your API (team1Games and team2Games are just for Hibernate's use):

        @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;
        }
    

    so to callers of your class, it's transparent that there are 2 properties.

这篇关于在JPA / Hibernate中建模两对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆