Hibernate does not remove orphans on OneToMany

I have some pretty simple relationships:

The team has a set of players:

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

And each player has a unique identifier and name.

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

I run a very simple code:

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

And I get the following as expected:

  • Sleep mode: select team_.id, team_.team_name as team2_0_ from TEAM, where team_.id =?
  • Sleep mode: select player_.id, player_.player_name as player2_1_ from player PLAYER_ where player_.id =?
  • Sleep mode: select player_.id, player_.player_name as player2_1_ from player PLAYER_ where player_.id =?
  • Sleep mode: select player_.id, player_.player_name as player2_1_ from player PLAYER_ where player_.id =?
  • Sleep mode: insert into TEAM values โ€‹โ€‹(team_name, id) (?,?)
  • Hibernate: insert into PLAYER values โ€‹โ€‹(player_name, id) (?,?)
  • Hibernate: insert into PLAYER values โ€‹โ€‹(player_name, id) (?,?)
  • Hibernate: insert into PLAYER values โ€‹โ€‹(player_name, id) (?,?)
  • Hibernation: updating set PLAYER TEAM_ID =? where id =? Hibernate: update PLAYER set TEAM_ID =? where id =? Hibernate: update PLAYER set TEAM_ID =? where id =?

Then I will do the following:

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

And expect the removal of orphan players, but I get:

  • Sleep mode: select team_.id, team_.team_name as team2_0_ from TEAM, where team_.id =?
  • Sleep mode: select player_.id, player_.player_name as player2_1_ from player PLAYER_ where player_.id =?
  • Sleep mode: select player_.id, player_.player_name as player2_1_ from player PLAYER_ where player_.id =?
  • Hibernate: PLAYER set TEAM_ID = null, TEAM_ID =?
  • : PLAYER TEAM_ID =? id =?
  • : PLAYER TEAM_ID =? id =?

- (id = 3) , ... , ?

+5
3

, , , .

, :

  • .

FK (id = 1).

2 .

, 1.

POV - -. 1, , id = 1, .

private Team createTeam(int players) {
    Team team = session.get(Team.class, 1);
    if (team == null) {
       team = new Team();
       team.setName("Bears");
       team.setId(1);
    }
    team.clearPlayers();

    for(int i=1 ; i<=players; ++ i){
        Player player = new Player();
        player.setId(i);
        player.setName("Player"+i);
        team.addPlayer(player);
    }
    return team;
}

// Team.java
private void clearPlayers() {
   players.clear();
}

, . , , HibernateErrors " ...". setPlayers() addPlayer() removePlayer()

private void adddPlayer(Player player) {
   player.setTeam(this);
   players.add(player);
}

private void removePlayer(Player player) {
   player.setTeam(null);
   players.remove(player);
}

, , make getPlayers() :

private Set<Player> getPlayers() {
   return Collections.unmodifiableSet(players);
}

, :)

+3

: @org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN). , :

@OneToMany (cascade = {CascadeType.ALL}, orphanRemoval = true) @org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)   @JoinColumn (name = "TEAM_ID" )

+1

mappedBy .

Player.

// in Player.java
@ManyToOne(mappedBy="players")
private Team team;

MappeedBy .

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

1-TO-M, . hibernate id .

:

id , player_name,team_id
0

All Articles