1

これはかなり初心者の質問です-私はそれを知っていることを知っておいてください.

一部のデータを一度ロードし、その Bean のすべてのインスタンスで使用するために静的変数にローカルにキャッシュする必要があるステートレス セッション Bean があります。データには、エンティティ Bean を介してアクセスできます。エンティティ インスタンスをキャッシュしても安全かどうか、またはクローンを作成する必要があるかどうか疑問に思っています。また、このエンティティにはサブエンティティもあります。

エンティティ Foo を呼び出します。Foo には Bar があります。私のセッション 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
}

私の質問:

  1. これは悪い考えですか?それは機能しますか?

  2. おそらくその getFoo() メソッドを必要とせずに、Foo データを一度ロードするより良い方法はありますか? Session クラスがロードされたときに静的に実行するのが理想的です。

コメントごとの新しい (正確な) サンプル コード:

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);
    }
}
4

1 に答える 1

2

ステートレス セッション Bean (SLSB) では、非 final 静的フィールドは許可されません。EJB3 仕様のセクション 21.1.2 から:

エンタープライズ Bean は、読み取り/書き込み静的フィールドを使用してはなりません。読み取り専用の静的フィールドの使用は許可されています。したがって、エンタープライズ Bean クラスのすべての静的フィールドを final として宣言することをお勧めします。

このルールは、インスタンスを複数の JVM に分散する際の一貫性を確保するためにあります。

したがって、あまり良い考えではありません。私の提案は、JPA プロバイダーがサポートする可能性のある 2 次キャッシュに依存し、それを透過的に処理できるようにすることです。

補足として、なぜあなたのBeanにこの行があるのか​​ 本当に疑問に思っています:

EntityManager em = Container.getInstance().getEntityManager();

管理された環境では、コンテナー管理のエンティティ マネージャーを使用し、SLSB に (@PersistenceContext注釈を使用して) 挿入する必要があります。

于 2010-07-09T17:45:42.433 に答える