0

次のように、注釈を使用して多対多の関係によってマッピングされた 2 つのエンティティ '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;
     }
}

次のサービス クラスを使用して、新しいチームを個人オブジェクトに追加し、結合テーブルを更新します (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) {
            ....
        }
   }
   ....
}

この構造は確かに機能しますが、個人オブジェクトのチーム コレクションにチーム オブジェクトを追加し、チーム オブジェクトを更新するのはおかしいと思います。論理的に間違っていませんか?このタイプの関係には、マスタースレーブ機能またはそのようなものがあることを知る必要があります。

どんなガイドも考慮されます。

4

1 に答える 1

1

マッピングが間違っています。多対多の双方向関連を定義する代わりに、同じ結合テーブルを使用して、2 つの多対多の単方向関連を定義しています。

双方向の関連付けには、常に所有者側と逆側があります。所有者側はmappedBy属性のない方です。逆側にはmappedBy属性が必要です。考えてみてください: 双方向の関連付けがどのようにマップされるかを Hibernate に 2 回伝える必要があるのはなぜでしょうか?

マッピングは次のようになります。

@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. つまり、個人とチームの間の関連付けを追加するには、個人のチーム コレクションにチームを追加する必要があります。別の方法でマッピングすることもできます。この場合、その人物をチームの人物コレクションに追加する必要があります。

また、CascadeType.ALLManyToMany アソシエーションを持つことは本当に疑わしいことに注意してください。チームを削除するときに本当にすべての人を削除し、削除された人のチームをすべて削除しますか?

于 2012-09-03T10:16:36.927 に答える