Hibernate不会删除OneToMany上的孤儿

Guy*_*and 5 hibernate hibernate-mapping jpa-2.0

我有以下非常简单的一对多关系:

团队有一组球员:

@Entity(name = "TEAM")
@Access(AccessType.PROPERTY)
public class Team{
    private Integer id;
    private String name;
    private Set<Player> players ;

    @Id
    @Column(name = "id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "team_name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(cascade = {CascadeType.ALL},orphanRemoval=true)
    @JoinColumn(name = "TEAM_ID")
    public Set<Player> getPlayers() {
        return players;
    }

    public void setPlayers(Set<Player> players) {
        this.players = players;
    }       
}
Run Code Online (Sandbox Code Playgroud)

每个玩家都有一个唯一的ID和名称.

@Entity(name = "PLAYER")
@Access(AccessType.PROPERTY)
public class Player implements Serializable{

    private int id;
    private String name;

    @Id
    @Column(name = "id")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Column(name = "player_name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
    return id == ((Player)obj).id;
    }
    @Override
    public int hashCode() {
        return id;
    }
}
Run Code Online (Sandbox Code Playgroud)

我运行一个非常简单的代码:

Team team = createTeam(3) // creates team with 3 players ids={1,2,3}
session.saveOrUpdate(team);
...

private Team createTeam(int players) {
    Team team = new Team();
    team.setName("Bears");
    team.setId(1);
    for(int i=1 ; i<=players; ++ i){
        Player player = new Player();
        player.setId(i);
        player.setName("Player"+i);
        team.addPlayer(player);
    }
    return team;
}
Run Code Online (Sandbox Code Playgroud)

我按预期得到以下内容:

  • Hibernate:从TEAM team_中选择team_.id,team_.team_name作为team2_0_,其中team_.id =?
  • 休眠:从PLAYER player_中选择player_.id,player_.player_name作为player2_1_,其中player_.id =?
  • 休眠:从PLAYER player_中选择player_.id,player_.player_name作为player2_1_,其中player_.id =?
  • 休眠:从PLAYER player_中选择player_.id,player_.player_name作为player2_1_,其中player_.id =?
  • Hibernate:插入TEAM(team_name,id)值(?,?)
  • Hibernate:插入PLAYER(player_name,id)值(?,?)
  • Hibernate:插入PLAYER(player_name,id)值(?,?)
  • Hibernate:插入PLAYER(player_name,id)值(?,?)
  • Hibernate:更新PLAYER设置TEAM_ID =?其中id =?Hibernate:更新PLAYER设置TEAM_ID =?其中id =?Hibernate:更新PLAYER设置TEAM_ID =?其中id =?

然后我做:

Team team = createTeam(2) // creates team with 2 player ids={1,2}
session.saveOrUpdate(team);
Run Code Online (Sandbox Code Playgroud)

并期望孤儿玩家被删除,但我得到:

  • Hibernate:从TEAM team_中选择team_.id,team_.team_name作为team2_0_,其中team_.id =?
  • 休眠:从PLAYER player_中选择player_.id,player_.player_name作为player2_1_,其中player_.id =?
  • 休眠:从PLAYER player_中选择player_.id,player_.player_name作为player2_1_,其中player_.id =?
  • Hibernate:更新PLAYER设置TEAM_ID = null其中TEAM_ID =?
  • Hibernate:更新PLAYER设置TEAM_ID =?其中id =?
  • Hibernate:更新PLAYER设置TEAM_ID =?其中id =?

哪个让孤儿播放器(id = 3)断开但没有删除...任何想法我做错了什么?

Pri*_*shi 0

在两个实体的关系中添加mappedBy 属性。

在播放器中添加团队。

// in Player.java
@ManyToOne(mappedBy="players")
private Team team;
Run Code Online (Sandbox Code Playgroud)

还有 Player 中的 MappeedBy。

//In Team.java
@OneToMany(cascade = {CascadeType.ALL},orphanRemoval=true,mappedBy="team")
    @JoinColumn(name = "TEAM_ID")
    public Set<Player> getPlayers() {
        return players;
    }
Run Code Online (Sandbox Code Playgroud)

当您有 1-TO-M 关系时,子级应该有其父级的引用。然后 hibernate 在内部使用父级的 id 作为子表中的外部。

您的子表将包含以下 3 列:

id , player_name,team_id
Run Code Online (Sandbox Code Playgroud)

  • 没有理由使关联成为双向的。无论如何,在双向关联中,只有一侧必须具有mappedBy 属性,因为它意味着:“去查看另一侧关联的映射”。 (2认同)