两个表可以互相引用吗?

时间:2016-11-04 18:53:23

标签: java hibernate jpa orm relational-database

我有两个表,Team和Player(一对多)。

我的第一个问题是,让两个表如此相互引用是不好的做法吗?

Team: (id (pk), name, captain_id (fk))
Player: (id (pk), name, team_id (fk))

我使用JPA和hibernate进行以下设置。

@Entity
public class Player {

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private int id;

   private String name;

   @ManyToOne
   @JoinColumn(name="team_id")
   private Team team;
}

@Entity
public class Team {

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private int id;

   private String name;
   private int captainId;


   @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
   private Set<Player> players;

在创建新Team时,创建它的Player的id将作为参数传递。它工作正常,但手动操作并不合适。

public void createNewTeam(Player player, Team team){

    Set<Player> players = new HashSet<Player>();
    Team team = new Team("Cowboys", player.getId(), players);    //player.getId is the captain()

    player.setTeam(team);
    players.add(player);

    PersistenceUtil.merge(team);    
}

有没有办法以某种方式更改实体以自动执行此操作?或者我需要更改表格吗?

我一直在尝试使用gson将对象转换为JSON,但无济于事。我认为它有一些循环引用的东西。 (是的,我是一个太深的菜鸟!)

3 个答案:

答案 0 :(得分:0)

你在这里描述的内容:

Team: (id (pk), name, captain_id (fk))
Player: (id (pk), name, team_id (fk))

错了,不应该这样配置。

如果要在两个实体之间配置一对多关联,

然后正确的方法是:

首先,确定哪个实体将是Many,哪个实体将是Single (One),在我们的例子中,它非常简单。每个玩家都属于One团队,每个团队都有Many个玩家。

团队 - &gt;一个

播放器 - &gt;许多

其次,如果你试图表示与桌子的关联,那么多人(玩家)应该拥有一个(团队)的fk,并且团队不应该持有玩家的fk,应该只有一个fk在这个协会。

为什么?

假设您在Team桌上拥有一支PK为211的团队,该团队有很多玩家可以说ID为100,101,102的玩家。

你在团队桌上不能拥有3条记录(对于3个不同的玩家100,101,102)具有相同的PK 211

答案 1 :(得分:0)

我认为必须有一名管理员加入球队和球员。 首先,他可以创建一个团队,其中包含有关团队的基本详细信 然后他可以添加一个有他的详细信息的球员,为他选择一个球队和一个标志,以表明他是否是队长。

所以表结构就是这样。

Team: (id (pk), name, description).
Player: (id (pk), name, team_id (fk), is_captain).

但正如你所说,玩家可以创建团队,然后每个玩家都可以创建一个团队。所以你必须通过一些角色来控制它。

所以好的方法是首先添加团队,然后由一些管理员添加球员。

答案 2 :(得分:-1)

这是可能的,但非常有限。如果你先添加一个Team,那么它的队长应该是空的,因为你还没有创建Player。然后,您必须在创建Player-Captain后更新您的团队。反之亦然。

我首先将队长属性移动给玩家:

Team: (id (pk), name)
Player: (id (pk), name, team_id (fk), is_captain)

这样您就不必来回更新。

您的功能类似于:

public void createNewTeam(Player player, Team team){

Set<Player> players = new HashSet<Player>();
Team team = new Team("Cowboys", players);    

player.isCaptain(true);
player.setTeam(team);
players.add(player);

PersistenceUtil.merge(team);    
}