どのように私は参加し、テーブルからエントリを削除するには、JPQLを使用していますか?
-
21-08-2019 - |
質問
私はこのような多対多の関係を持っているJPAオブジェクトを持っています:
@Entity
public class Role {
//...
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
name="RolePrivilege",
joinColumns=
@JoinColumn(name="role", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="privilege", referencedColumnName="ID")
)
private Set<Privilege> privs;
}
がありRolePrivilegeのためのJPAオブジェクトではありませんので、私はロールオブジェクトのPRIVSフィールドからエントリを削除するには、JPQLクエリを記述するかどうかはわかりません。例えば、私はこれを試してみたが、それは動作しません。それはRole.privsがマップされていないと文句を言います。
DELETE FROM Role.privs p WHERE p.id=:privId
私が試して他に何かわかりません。私は、もちろん単なる結合テーブルRolePrivilegeから削除ネイティブクエリを書くことができます。しかし、私はそうすることが、ネイティブクエリによって更新されない、ローカルにキャッシュされたオブジェクトでひどく相互作用することを心配しています。
は、次のように結合テーブルからエントリを削除するにはJPQLを書くことも可能ですか?私は、すべての役割のオブジェクトをロードし、それぞれのPRIVSコレクションからエントリを削除してから、それぞれの役割を持続することができない場合。しかし、それは簡単なJPQLクエリは一度にすべてを尽くす場合があることを行うために愚かなようです。
解決
JPQLの更新や文を削除するエンティティ名、いないテーブル名を参照する必要があるので、私はあなたが提案してきたアプローチと運の外にいると思います。
あなたのJPAプロバイダによっては、簡単な生のSQL文を使用してJoinTableからエントリを削除できます(100%移植する必要があります)、その後、プログラムのデータを立ち退かせるためにあなたのキャッシュプロバイダのAPIと対話します。休止状態で例えばあなたが第二レベルのキャッシュからすべての「Role.privs」コレクションを期限切れに追い出し()を呼び出すことができます:
sessionFactory.evictCollection("Role.privs", roleId); //evict a particular collection of privs
sessionFactory.evictCollection("Role.privs"); //evict all privs collections
残念ながら、私は正確にサポートされているものを確実に知るために十分なJPAのAPIでは動作しません。
他のヒント
私も(参加表に含まれている)多対多の関係を削除するには、JPQLのアプローチを探していました。もちろん、そこにORM内のテーブルの概念ませんので、我々はDELETE操作を使用することはできません...しかし、私はこれらのケースのための特別な作業があった望みます。 LINKとUNLINKような何か。たぶん、将来の機能?
とにかく、私はこの必要性を達成するために何をしてきたエンティティBeanで実装コレクション、多対多の関係をマッピングしたもので動作するようになっています。
たとえば、私はコースで多対多の関係を持つクラスの学生を得た場合:
@ManyToMany
private Collection <Courses> collCourses;
私は、エンティティにそのコレクションのためのゲッターとセッターを構築します。次に、EJBからたとえば、私は希望コースを追加または削除、ゲッターを使用したコレクションを取得し、最終的に、新しいコレクションを割り当てるためにセッターを使用しています。そして、それは行われています。それは完璧に動作します。
しかし、私の主な心配はパフォーマンスです。 ORMは(私は間違っていない場合)、すべてのオブジェクトの巨大なキャッシュを保持しますが、さらに速く動作するようにそれを使用することになっている、私は疑問に思うのコレクションからすべての、すべての要素を取得することは本当に効果がある場合...
私にとっては同じくらい非効率的なテーブルからレジストリを取得するなどだと、純粋なJavaの代わりに、内部のDBエンジン(SQL、JPQL ...)とundirectly直接働くか、クエリ言語を使用してそれらをポストフィルタので。
Javaはオブジェクト指向言語であり、ORMの全体のポイントは、あなたから参加したテーブルと、このような内容を非表示にすることです。そのためにも奇妙なだろう影響を考慮せずに、結合テーブルからの削除を検討します。
いいえ、エンティティのためであるJPQL、でそれを行うことはできません。
両端にエンティティを取得し、そのコレクションをクリア。これは、参加するテーブルエントリを削除します。オブジェクト指向ます。