JPA + Hibernate - 从@OneToMany关系重新连接实体

时间:2010-02-17 16:21:32

标签: hibernate orm jpa spring-mvc spring-roo

考虑以下简单示例: 一支球队有很多球员,一名球员可能只属于一支球队。

@Entity
public class Team {

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team")
    @Cascade({  org.hibernate.annotations.CascadeType.ALL,
                org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    private Set<Player> player = new HashSet<Player>();

}

@Entity
public class Player {

    @NotNull
    @ManyToOne(targetEntity = Team.class)
    @JoinColumn(name = "team_id")
    private Team team;

}

我想要实现的目标是将A队的所有球员转移到B队并随后删除A队。我对A队的球员进行了循环,并将他们的球队设置为B队(这里:“这个”):

Iterator<Player> iterator = teamA.getPlayer().iterator();
while(iterator.hasNext()){
 Player player = iterator.next();
 player.setTeam(this);
    player.merge();
}
teamA.remove();

之后刷新(autoflush),但我也尝试在teamA.remove()之前刷新。此代码运行时没有错误,但之后由于级联配置,团队A中的玩家将从我的数据源中删除,因为teamA.remove()会导致从A队中删除所有玩家。

我想知道为什么他们仍然与团队A相关联,因为我也尝试(并在调试器中检查)从Set中删除所有玩家,因此当调用teamA.remove()时,该集合为空。在这些情况下抛出的异常要么声明“已删除的实体已传递给持久性”,要么“已分离的实体已传递给持久性”。它当然有效,如果我创建一个新的瞬态播放器,复制所有属性和.persist()。

如何通过简单地“重新关联”这段关系来做到这一点?

4 个答案:

答案 0 :(得分:1)

你试过了吗?

team2.setPlayers(team1.getPlayers();
team1.setPlayers(null);
for (Player player : team2.getPlayers() {
   player.setTeam(team2);
}

答案 1 :(得分:0)

我认为你必须在调用团队中的删除之前清空该设置。但你说你试过了吗?

新团队是否为持久性实体?

答案 2 :(得分:0)

我认为罪魁祸首是DELETE_ORPHAN。来自Annotations参考:

  

DELETE_ORPHAN仅适用于@OneToMany关联,并指示delete()/ remove()操作应应用于从关联中删除的任何子对象。换句话说,如果子节点被持久父节点取消引用,并且如果使用DELETE_ORPHAN,则删除“孤立”子节点。

但这不是你想要的,因为你正在“重新定位”玩家。

答案 3 :(得分:0)

我认为在你改变玩家团队后,你应该调用flush(),然后在teamA上调用refresh(),然后在teamA上调用remove()。