ManyToMany关系奇怪的行为

时间:2012-09-03 09:16:12

标签: hibernate jpa-2.0

我有两个实体'Person'和'Team',它们使用注释按多对多关系映射,如下所示:

@Entity
public class Perosn implements Serializable {
      ....
      private Collection<Team> teams;
      ....

     @ManyToMany(fetch = FetchType.LAZY)
     @Cascade({CascadeType.ALL})
     @JoinTable(name = "person_team",
            joinColumns = { @JoinColumn(name = "person_id")},
            inverseJoinColumns = {@JoinColumn(name = "team_id")})
     public Collection<Team> getTeams() {
        return advisers;
     }
}

@Entity
public class Team implements Serializable {
      ....
      private Collection<Person> persons;
      ....

     @ManyToMany(fetch = FetchType.LAZY)
     @Cascade({CascadeType.ALL})
     @JoinTable(name = "person_team",
            joinColumns = { @JoinColumn(name = "team_id")},
            inverseJoinColumns = {@JoinColumn(name = "person_id")})
     public Collection<Person> getPersons() {
        return advisers;
     }
}

我使用以下服务类将新团队添加到person对象并更新连接表(添加包含personId和teamId的新记录):

@Service("teamService")
public class TeamService extends DataAccess {
    ....
    public void addTeamToPerson(String teamId, String personId) {

        Team team= getTeam(teamId);
        Person person= personService.getPerson(personId);
        person.getTeams().add(team);
        super.update(team);
    }
    ....
}

public abstract class DataAccess<E> {

    private EntityManager manager;
    ....
    public void update(E object) {
        try {
            manager.getTransaction().begin();
            manager.merge(object);
            manager.getTransaction().commit();
        } catch (Exception e) {
            ....
        }
   }
   ....
}

这种结构确实有效,但我认为将团队对象添加到人员对象的团队集合并更新团队对象是很奇怪的。 这在逻辑上是错误的吗?我需要知道在这种关系中存在主从特征或类似的东西。

任何指南都会被视为。

1 个答案:

答案 0 :(得分:1)

您的映射是错误的:您不是定义多对多双向关联,而是使用相同的连接表定义两个多对多单向关联。

双向关联始终具有所有者方和反方。所有者方是没有mappedBy属性的方。反面必须具有mappedBy属性。想一想:为什么你需要告诉Hibernate两次如何映射双向关联?

映射应为:

@Entity
public class Person implements Serializable {
      ....
      private Collection<Team> teams;
      ....

     @ManyToMany(fetch = FetchType.LAZY)
     @Cascade({CascadeType.ALL})
     @JoinTable(name = "person_team",
            joinColumns = { @JoinColumn(name = "person_id")},
            inverseJoinColumns = {@JoinColumn(name = "team_id")})
     public Collection<Team> getTeams() {
        return advisers;
     }
}

@Entity
public class Team implements Serializable {
     ....
     private Collection<Person> persons;
     ....

     @ManyToMany(fetch = FetchType.LAZY, mappedBy = "teams")
     @Cascade({CascadeType.ALL})
     public Collection<Person> getPersons() {
        return advisers;
     }
}

在这种情况下,所有者方为Person。这意味着要在人员和团队之间添加关联,您需要将团队添加到此人的团队集合中。您可以选择以其他方式映射它,在这种情况下,您需要将此人添加到团队人员集合中。

另外,请注意,在ManyToMany关联中使用CascadeType.ALL真的很可疑:您是否真的想在删除团队时删除所有人员,并删除已删除人员的所有团队等?