IBMは、EntityManagersを使用するためのベスト・プラクティスはget / use/closeであると提案しています。EntityManagerが閉じられていない場合、同じEntityManagerが複数のスレッドで使用され、次のエラーが発生する可能性があります。
<openjpa-2.1.2-SNAPSHOT-r422266:1179900 fatal general error> org.apache.openjpa.persistence.PersistenceException: Multiple concurrent threads attempted to access a single broker. By default brokers are not thread safe; if you require and/or intend a broker to be accessed by more than one thread, set the openjpa.Multithreaded property to true to override the default behavior.
次のように、fetch =LAZYとしてマップされたOneToManyコレクションを持つオブジェクトをロードする場合:
public T find(Object id) {
T t = null;
EntityManager em = getEm();
t = em.find(type, id);
em.close();
return t;
}
EntityManager getEm() {
if(this.em ==null || !this.em.isOpen()) {
this.em = emf.createEntityManager();
}
return this.em;
}
誰かがゲッターを呼び出すまでに、EntityManagerが閉じられるため、コレクションは常にnullになります。コレクションは、フェッチがEAGERの場合にのみロードされますが、その結果、毎回SQL結合が発生し、速度が低下します。
したがって、これは「マルチスレッド」エラーか、openjpa.Multithreaded = trueのいずれかです。これは悪い習慣であるか、コレクションが必要ない場合でも毎回SQL結合があるために低速です。レイジーフェッチで高速になり、ベストプラクティスのみを使用して実行されるように、適切に実行する方法はありますか?