これは、「カスケード」の問題ではなく、多対多のマッピングで 1 つの関係を削除することに関する Hibernate の生成された SQL に関する質問です。
JPA 2 を使用し、その実装として休止状態にします。
User と Role の 2 つのモデルがあります。1 人のユーザーが複数のロールを持つことができ、1 つのロールが複数のユーザーを持つことができるため、これらは多対多のマッピングになります。
@Entity
class User{
@Id Long id;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinTable(name = "user_role", inverseJoinColumns = @JoinColumn(name = "role_id"),
joinColumns = @JoinColumn(name = "user_id"))
private List<Role> roles;
}
@Entity
class Role{
@Id Long id;
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REFRESH, mappedBy = "roles")
private List<User> users;
}
マッピングはうまく機能し、hibernate はこのマッピング用に 3 つのテーブルを自動作成します
table user
table role
table user_role
ここに問題があります。私が望むのは、1人のユーザーから1つのロールを削除することです(ユーザーまたはロールを削除するのではなく、1人のユーザーと1つのロールの間の関係を1つだけ削除することは、テーブルから1つのレコードを削除するだけでよいことを意味しますuser_role
)。これが私が試したコードです:
public void removeOneRoleFromUser(long userId, long roleId){
User user = userService.getById(userId);
Role role = roleService.getById(roleId);
user.getRoles().remove(role); //here
userService.update(user);
}
このコードを実行すると、実際にロールがユーザーから削除されました。しかし、休止状態で生成されたSQLを確認すると、期待したものではありません.休止状態で生成されたSQLは次のとおりです。
delete from user_role where user_id = {userId}
insert into user_role values({user_id}, {role_id_not_removed})
...
insert into user_role values({user_id}, {another_role_id_not_removed})
したがって、1 人のユーザーから 1 つのロールを削除するには、休止状態で最初にユーザーからすべてのロールを削除してから、削除してはならないロールを 1 つずつユーザーに追加します。
そして、私が期待しているのは、それをアーカイブする1つのSQL文だけです:
delete from user_role where user_id = {userId} and role_id = {role_id}
UserRoleMapping
テーブルにマッピングする別のエンティティを導入するなど、これをアーカイブできる他の方法があることを知っていますuser_role
。次に、1つの UserRoleMapping インスタンスを直接削除すると、1人のユーザーから1つのロールが削除されます。しかし、現在のソリューションで期待できるソリューションがあるかどうかを知りたいです。