既存のインスタンスステートレス内のステートフル、Java EE 6にアクセス

StackOverflow https://stackoverflow.com/questions/9384368

質問

ステートレスビーン内のステートフルセッションビーンにアクセスすることは可能ですか?

私の問題は、私がユーザーと呼ばれるセッションBeanを持っていることであり、無国籍の豆内でユーザー情報にアクセスしたいということです...

私はこのようにやっています:

EJBサイド:

@Stateless
public class OfferManagerBean implements OfferManagerLocal, OfferManager
{
    @Resource 
    private SessionContext context;
    @EJB
    private ro.project.ejb.interfaces.User user;
    public String getUsername()
    {
        user = (ro.project.ejb.interfaces.User) context.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
        return user.getUsername();
}

クライアント側

 User user = (User) ctx.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
 user.setUsername("Alex");

 OfferManager offerManager = (OfferManager) ctx.lookup("java:global/project/projectEJB/OfferManagerBean!ro.project.ejb.interfaces.OfferManager");
 assertEquals(offerManager.getUsername(), "Alex");

このテストケースの結果は次のとおりです java.lang.AssertionError: expected:<null> but was:<Alex>

それは失敗します..ステートフルな豆が私に新しいインスタンスを返すように私がどのように要求しているかのようです...

  1. なぜこれが機能していないのか知っています。私のテストが失敗したため:p。新しいインスタンスを取得します。
  2. EJBでログインしているユーザーの特定の権限を確認したいのですが、クライアント側に頼りたくないので、そこで間違いを犯したり、他の開発者にプロジェクトのGUIを作るように指示したりします。
  3. Java EEセキュリティを使用したくないBeucause RCPアプリケーションでログインする方法がわかりません
  4. 私の主な質問は、EJB内でセッションBean(クライアントが所有するものと同じ)にアクセスするにはどうすればよいですか?そしてどうやって?

私はこの男が尋ねていることとほぼ同じことを尋ねています: RMI EJBコールでの再利用可能なログインセッションの概念

私はそれをしたいのですが、Jaasではありません...

前もって感謝します

役に立ちましたか?

解決

あなたがすべき 一度もない 注入a @Stateful aの豆(SFSB) @Stateless Bean(SLSB)。 SFSBは、クライアントが生きている限り生きています(クライアントは、SFSBが注入されるインスタンスであり、この場合はSLSB自体です)。ただし、SLSBは意図されています ステートレス そして、ほとんどのコンテナはプールにそれらを持っています。したがって、SLSBが使用後にプールに戻るたびに、他の場所で完全に再利用されますが、SLSBが初めて作成されたときと同じSFSBインスタンスを保持します!これは、望ましくない結果につながる可能性があります。

また、JNDIからSFSBを入手するたびに、 真新しい SLSBとは異なるインスタンス いいえ 他の場所で共有。 SFSBのクライアントは、JNDIからSFSBを入手した現在のクライアントクラスインスタンスです。このインスタンスを自分で保持し、トランザクションの実行が終了するまで同じインスタンスを再利用することになっています。方法の1つは、HTTPセッションで自分で保存するか、使用しているMVCフレームワークのセッションスコープマネージドビーンに保存することです。

機能的要件は私には完全に明らかではないので、あなたの特定の問題を解決する方法を適切な答えに与えるのは難しいですが、私はあなたが 実際に SFSBではなく、HTTPセッションにユーザーを保存する必要があります。セッション豆に関する最も一般的な初心者の間違いは、EJBコンテキストの「セッション」をHTTPセッションと誤って解釈することです。

より詳細な説明については、同じ種類の質問に関するこの関連する答えも参照してください。 JSFリクエストスコープ豆は、すべてのリクエストで新しいステートフルセッション豆を再現し続けますか? あなたの質問履歴によれば、あなたはJSFに精通しているので、この答えは簡単に理解できるはずです。

他のヒント

一般に、Stateless Bean内の特定の既存のStateful Session Bean Beanにアクセスすることができます。たとえば、ステートレスセッションBeanのビジネス方法への議論として与えられることがあります。

しかし、あなたがしようとしていることはうまくいきません。理由は、Dependy Injection(@EJB)とLookup(CTX.Lookup ...)の両方がNewInstanceを呼び出すことが保証されており、その結果、新しいインスタンスが得られるためです。

これは、次の言葉で仕様で説明されています。

セッションBean Instanceの寿命は、クライアントが依存関係インジェクションまたはJNDI検索を通じてステートフルセッションBeanインスタンスへの参照を取得したとき、またはクライアントがセッションBeanのホームインターフェイスで作成メソッドを呼び出したときに始まります。これにより、コンテナはセッションBeanクラスのNewInstanceを呼び出して、新しいセッションBeanインスタンスを作成します。

他の人がすでに十分に明確ではなかった場合:あなたはそれを間違っています! ;)

私はそれが混乱しているかもしれないことに同意しますが、EJBセッションの豆の唯一のセッションは、あなたがinititatialContextから入手したプロキシビーンに保持されます。

このコンテキストから取得するさまざまな豆は、共通のセッションを共有しません。 EJBでは、豆はEJBセッションに保管されていませんが、このセッションです。

言い換えれば、initialContext(コードのCTX)は、HTTPSESSIONのEJB等価性ではありません。

さらに悪いことに、コードではユーザーがEJB Beanであることです。これは間違っています。

ユーザーはaです 名詞 あなたのアプリケーションで。これらは、JPAエンティティまたは単純な「通常の」Java Beansで表されます。 EJBは実装するためです 動詞 アプリケーションでは、サービス、DAO、リポジトリなど。

ステートフルセッションの豆の州は、ビジネスプロセス中にデータをモデル化することを保持することになっています(キャッシュ、ロック、予約などの目的)。この状態がモデルデータである必要はありません。

私のアドバイス:現在の「デザイン」を行かせてください。修正しようとしないでください。正当化しようとしないでください。それを手放し、コードを削除し、振り返らないでください。 EJBについての良い本を読んでから始めましょう。

幸運を!

SFSB&SLSBの使用で正しい/間違っているかどうかは検証していません。しかし、以下はあなたの問題に対する答えです

オプション1:サーブレットから、SFSBのJNDIルックアップを実行します。これは一度になるはずです。 sfsbの返された参照をhttpsesssionに保存します。ユーザーの詳細を保存するためにSFSBインスタンスを必要とするSLSBメソッドを呼び出す場合、上記のSFSB参照オブジェクトをSLSBメソッドにパラメーターとして渡します。次に、SLSBメソッドからアクセスし、ユーザーデータを保存します。

Option-1の問題:あなたはあなたの永続的なメカニズム(SFSB)をUIコードに結び付けています(httpsessionで保存して渡すので)。明日、キャッシュのような別の永続メカニズムに変更したい場合は、多くの再作業を行う必要があります。繰り返しますが、SLSBメソッドをWebサービスとして公開する場合は、SFSBオブジェクトリファレンスをXML-Izeできないため、それを行うことはできません。要するに、悪い選択肢。

オプション2:ビジネス層の一部のクラスに静的ハッシュマップを持っています。すべてのトランザクション、IDのような一意のトランザクション属性があると仮定します。ビジネス層からトランザクションを開始するときに、SFSBを作成し、IDをキーとして静的ハッシュマップに参照を保存します。 SLSBサービスメソッドを呼び出すときは、このIDを渡します(各トランザクションには一意のIDがあると仮定します)。 SLSBメソッドから、IDを使用して静的ハッシュマップに保存されているSFSB参照を検索します。ストレージに使用してください。このオプションでは、UI&SFSBが結合されていません。明日、永続性メカニズムを鳴らしたい場合は、BC Tier内で変更が制限されるため、クライアントに影響を与えることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top