Ho il seguente abbastanza semplice a molti rapporti:Hibernate non elimina orfani su OneToMany
squadra ha una serie di giocatori:
@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;
}
}
e ogni giocatore ha un unico id & nome.
@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;
}
}
Ho eseguito un codice molto semplice:
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;
}
E ottengo il seguente come previsto:
- Hibernate: selezionare team_.id, team_.team_name come team2_0_ da TEAM team_ dove team_.id =?
- Hibernate: selezionare player_.id, player_.player_name come player2_1_ dal player PLAYER dove player_.id =?
- Hibernate: selezionare player_.id, player_.player_name come player2_1_ dal player PLAYER dove player_.id =?
- Hibernate: selezionare player_.id, player_.player_name come player2_1_ dal player PLAYER dove player_.id =?
- Hibernate: insert into TEAM (TEAM_NAME, id) valori
- Hibernate (,??): Inserire nel PLAYER (PLAYER_NAME, id) valori
- Hibernate (,??): Insert into PLAYER (PLAYER_NAME, id) valori (?,?)
- Ibernazione: inserire nei valori PLAYER (player_name, id) (?,?)
- Hibernate: aggiornamento PLAYER set TEAM_ID =? dove id =? Hibernate: aggiornamento PLAYER set TEAM_ID =? dove id =? Hibernate: aggiornamento PLAYER set TEAM_ID =? dove id =?
Poi più tardi lo faccio:
Team team = createTeam(2) // creates team with 2 player ids={1,2}
session.saveOrUpdate(team);
e si aspettano i giocatori orfani da eliminare ma ottengo:
- Hibernate: selezionare team_.id, team_.team_name come team2_0_ da TEAM team_ where team_.id =?
- Hibernate: selezionare player_.id, player_.player_name come player2_1_ dal player PLAYER dove player_.id =?
- Hibernate: selezionare player_.id, player_.player_name come player2_1_ dal player PLAYER dove player_.id =?
- Hibernate: aggiornamento PLAYER set TEAM_ID = null dove TEAM_ID =?
- Hibernate: aggiornamento PLAYER set TEAM_ID =? dove id =?
- Hibernate: aggiornamento PLAYER set TEAM_ID =? dove id =?
Quale lascia disconnesso il lettore orfano (id = 3) ma non cancellato ... Qualche idea su cosa faccio di sbagliato?
Cosa sta facendo il metodo 'createTeam()'? – dcernahoschi
crea una squadra con i giocatori –
Potrebbe essere correlato o meno ma lo testiamo su HSQL –