JPA 2.0と休止状態を使用しています。次のように、ユーザークラスとグループクラスがあります。
public class User implements Serializable {
@Id
@Column(name="USER_ID")
private String userId;
@ManyToMany
@JoinTable(name = "USER_GROUP",
joinColumns = {
@JoinColumn(name = "GROUP_ID")
},
inverseJoinColumns = {
@JoinColumn(name = "USER_ID")
}
)
private Set<Group> groupList;
//get set methods
}
public class Group
{
@Id
@Column(name="GROUP_ID")
private String groupId;
@ManyToMany(mappedBy="groupList")
private Set<User> memberList;
//get set methods
}
そして、ユーザーとグループを作成し、ユーザーをグループに割り当てます。
私が持ちたいのは、グループを削除すると、グループが(もちろん)削除され、グループが持つすべてのユーザーとグループの関係がUSER_GROUP結合テーブルから自動的に削除されますが、ユーザー自体はUSERテーブル。
上記のコードでは、グループを削除するとGROUPテーブルの行のみが削除され、ユーザーはUSER_GROUP結合テーブルで削除されたグループへのエントリを保持します。
このようにカスケードをUserクラスに入れた場合:
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "USER_GROUP",
joinColumns =
{
@JoinColumn(name = "GROUP_ID")
},
inverseJoinColumns =
{
@JoinColumn(name = "USER_ID")
})
private Set<Group> groupList;
グループを削除すると、ユーザーも削除されます!
私が望むものを達成する方法はありますか?
マッピング方法では、User
はリレーションシップの管理側であるため、結合テーブルの更新を担当します。
JoinTable
マッピングをUser
からGroup
に変更し、groupList
のUser
プロパティをmappedBy
属性を持つように変更します。これにより、グループが関係の管理側に変更され、グループへの永続/更新呼び出しが行われ、結合テーブルが管理されます。
ただし、グループをユーザーに追加し、ユーザーを保存して続行することはできません。代わりに、グループにユーザーを追加し、グループを保存して変更を確認する必要がありますが、双方向の多対多を持つことで、とにかくその関係を密接に管理できることを願っています。
別の角度から問題を見る:
FK制約を多対多のマッピングテーブルに追加できます。実際、データ整合性の理由から、DBには常にFKが必要です。この場合、たとえば、マッピングテーブルに孤立行を静かに残しながら、少なくともユーザーを削除できませんでした。
FKがある場合は、制約でon カスケード参照アクションの削除 を指定できます。DBは、要求されたように、エンティティではなくマッピングテーブルの自動削除を管理します。
既に示したように、ユーザー側からカスケードする必要がない場合は、関係のグループ所有者を作成します。
次に、cascade=CascadeType.MERGE
グループを削除するときにユーザーをカスケード削除しないようにします。
このようなことができます
@PreRemove
private void removeMembers() {
this.memberList.clear();
}