セッションが終了した後、エンティティBeanへの参照を保存するのは安全ですか?
-
13-09-2020 - |
質問
これはかなりのニュービーの質問です - 私はそれを知っていることを知ってください。
私は一度にデータをロードして、そのBeanのすべてのインスタンスで使用するための静的変数でローカルにキャッシュする必要があるステートレスセッションBeanを持っています。データはエンティティBeanを介してアクセスできます。エンティティインスタンスをキャッシュしても安全なのか、それを複製する必要がある場合は疑問に思います。また、このエンティティにはサブエンティティもあります。
エンティティfooを呼び出します。Fooにはバーがあります。私のセッションBeanでは、このようなことをしたいです。
private static final FOO_ID = 123L;
private static Foo foo;
private static Foo getFoo(EntityManager em) {
if (foo != null)
return foo;
return foo = (Foo) em.find(Foo.class, FOO_ID);
}
public void someBusinessMethod() {
EntityManager em = Container.getInstance().getEntityManager();
Foo foo = getFoo(em);
Bar bar = foo.getBar();
// do some stuff with foo and bar
}
.
私の質問:
-
これは悪い考えですか?それはうまくいくのでしょうか?
-
fooデータを1回、おそらくそのgetfoo()メソッドを必要とせずにロードするのは良い方法ですか?セッションクラスがロードされたときに静的にそれをすることは理想的なようです。
新しい(正確な)コメントごとのサンプルコード:
public class Foo { // entity
private Long id;
private String name;
// getters and setters
}
public class Bar { // entity
private Long id;
private String name;
// getters and setters
}
public class FooHelper implements Helper {
private static final long FOO_ID = 123L;
private Foo foo;
public FooHelper() {
// use FOO_ID to look up a Foo & cache it locally
}
@Override
public void addBar(EntityManager em) {
Bar bar = new Bar();
bar.setName(foo.getName());
em.persist(bar);
}
public class StatelesSessionBean {
private static final Helper helper = new FooHelper();
public void someBusinessMethod() {
@PersistenceContext
EntityManager em;
helper.addBar(em);
}
}
.解決
ステートレスセッションBean(SLSB)では、最終的な静的フィールドが許可されていません。EJB3仕様から、セクション21.1.2:
Enterprise Beanは読み書き静的フィールドを使用しないでください。読み取り専用静的フィールドを使用することができます。したがって、Enterprise Beanクラスのすべての静的フィールドを最終的なものとして宣言することをお勧めします。
この規則は、複数のJVMにインスタンスを配布するときに一貫性を確保するための一貫性を確保しています。
だから本当に良い考えではありません。私の提案は、JPAプロバイダーがサポートし、透過的にそれを扱うことができるようにする2番目のレベルキャッシュに頼ることです。
サイドノートとして、私は本当にあなたがあなたのBeanにこの行を持っている理由:
EntityManager em = Container.getInstance().getEntityManager();
.
管理環境では、 Container管理 Entity Managerを使用してSLSBに注入する必要があります(@PersistenceContext
注釈を使用)。