1

私は Hibernate が初めてで、コレクションを含むエンティティを永続化しようとしています。

Set である属性を含むクラス User があります。

class User{

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "user_id", referencedColumnName = "id")
   @Valid
   @Nullable
   public Set<Permission> getPermissions()
   {
      return permissions;
   }
}

新しいアクセス許可セットでユーザーを更新し、それを保存しようとすると、アクセス許可が再び元の値にリセットされ、他のすべての値が更新され、そうでないアクセス許可のみが更新されます。

@Transactional(readOnly = false)
   @Override
   public User update(User user)
      entityManager.merge(user);
      entityManager.flush(); 
      entityManager.refresh(user); 
      return user;

推移的永続性と切り離されたオブジェクトについて読みましたが、まだ機能しません。

私が間違っていることはありますか?

4

2 に答える 2

2

で試してみてください

@Transactional(readOnly = false)
@Override
public User update(User user)
    return entityManager.merge(user);
}

他の呼び出しは不要であり、コードが乱雑になります。そして、の結果を無視しますmerge()。これは、デタッチされ、そのまま残され、ユーザーが引数として渡された、更新されたアタッチされたバージョンです。

また、関連付けにはカスケードALLがあるため、上記ではユーザーフィールドと、ユーザーに関連付けられている権限が更新されるだけではないことに注意してください。また、権限をマージします。したがって、引数として渡されたユーザーのアクセス許可の状態は、これらのアクセス許可の添付バージョンにコピーされ、データベースに保存されます。

于 2012-07-19T12:27:03.363 に答える
0

おそらく、コレクション全体を置き換えていますか?全体を置き換えるのではなく、既存のコレクションを取得し、その内容を更新するために .add() および .remove() を呼び出すのが最善であることがわかりました。

また、代わりに @ElementCollection を使用してみてください

@ElementCollection
@CollectionTable(name="PERMISSION",
        joinColumns={@JoinColumn(name="USER_ID")}
)
private Set<Permission> permissions;

唯一の注意点は、Permission クラスを @Embeddable でマークする必要があることです。また、アクセス許可をトップレベル オブジェクトとして直接クエリできるとは思えません (ユーザーを経由する必要があります)。また、Permission オブジェクトには、そのユーザーへのポインターがありません。

これをクエリする方法のサンプル hql を次に示します。

 select p from User u join u.permissions p where p.name=?
于 2012-07-19T12:35:00.707 に答える