2

これは、「カスケード」の問題ではなく、多対多のマッピングで 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つのロールが削除されます。しかし、現在のソリューションで期待できるソリューションがあるかどうかを知りたいです。

4

1 に答える 1

2

この説明が正しいかどうかは確認していませんが、良い点があります。

インデックス列がない場合、List は実際にはバッグです。順序がなく、重複が許可されます。したがって、Hibernate は、ユーザーのロールのリストで同じロールが 2 回ある可能性があると見なします。

delete from user_role where user_id = ? and role_id = ?したがって、リストから削除したロールだけでなく、複数のロールが削除される可能性があるため、発行は不可能です。

インデックス列を追加するか、 のSet<Role>代わりに を使用してみてくださいList<Role>

于 2012-05-18T16:40:08.727 に答える