最初に、私が明白なことを尋ねる場合、またはご質問が本質的に根本的に愚かである場合には、ごめんなさい。JPAは一度だけクエリを作成します
より多くの学問的質問は、EntityManager
にまたがっているか、それと独立している(名前が付けられているかどうかなど)JPAクエリを作成できるかどうかを知る必要があります。基本的には、は常に実行されます。。私はEnitity ManagerオブジェクトのcreateXXXQuery
メソッドからQueryインスタンスを取得することしかできないと理解していますが、まだ別の方法がありますか?
これが何をしようとしていますされているもので、
public class MyRepo {
@PersistenceContext
private EntityManager em;
private Query aQueryIntentedtoBePreparedOnlyOnce;
@PostConstruct
public void prepareMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce = em.createQuery("...."); // Query with positional params
}
public void executeMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce.getResultList();
}
}
これは完全に最初の時間を実行します。しかし、2回目は「Entity Manager Closed」と言います。これは、EMのトランザクションスコープが原因であると私は理解しています。
このEMはコンテナ管理(JTA - Spring)のため、トランザクション間で拡張することはできません。また、Session Beanの使用はオプションではありません。では、このクエリを1回だけ作成する方法はありますか?
PS:名前付きクエリとクエリキャッシュは、どこにありますか?名前付きクエリでは、毎回createNamedQuery
のように見えます。クエリキャッシュプランとは何ですか?そこには良いドキュメントがありますか?
もう1つの質問は、EMまたは接続(JDBC)でクエリが作成されるのはなぜですか?クエリを準備するためにどのDBと話しているのかを知る必要はありませんか?適切な接続なしで決して実行することができないようになっていますか?
できません。単純な休止状態では、 'DetachedCriteria'を使うことができますが、それでも実行のための' Criteria'インスタンスになる必要があり、 'Session'(またはJPA用語では' EntityManager')が必要です。しかし、なぜあなたはこれをしたいですか?パフォーマンスは向上しません(より多くのメモリが使用されます)。実際のクエリはJDBCドライバによってキャッシュされます(設定されている場合)。 –
@M。 Deinum私はこれを行う必要はありません、ちょうど私が何かを欠場していたかどうか疑問に思う。なぜそれはより多くの記憶を消費するのだろうか?クエリは、私のレポオブジェクトのメンバーですか?パラメータを使用してSQLを変更しても、JDBCドライブはキャッシュされたSQLを使用していませんか? – anchreg
いいえ。 'PreparedStatement'は、バインドされたパラメータを持つクエリではなくキャッシュされるためです。あなたはもっと多くのオブジェクトをメモリに持っているので、より多くのメモリがあります。今は非常に短い寿命のオブジェクトを持っています。これはかなり速くメモリから取り除かれます。 –