2009-03-11 20 views
1

App Serverの稼働時間の間、オブジェクトをデータ構造に格納することは可能ですか?基本的には、このデータ構造とインターフェースするEJBが必要ですが、完全なデータベースソリューションは必要ありません。データ構造内のEJBと格納オブジェクト(マップ、リストなど)

例として、私はこのダミー動物オブジェクトを作った:

package com.test.entities; 

public class Animal implements java.io.Serializable { 

    private static final long serialVersionUID = 3621626745694501710L; 
    private Integer id; 
    private String animalName; 

    public Integer getId() { 
     // TODO Auto-generated method stub 
     return id; 
    } 
    public void setId(Integer id){ 
     this.id=id; 
    } 
    public String getAnimalName(){ 
     return animalName; 

    } 
    public void setAnimalName(String animalName){ 
     this.animalName=animalName; 
    } 
} 

だからここEJBリモートインタフェースである:ここでは

package com.test.beans; 

import java.util.Map; 

import javax.ejb.Remote; 

import com.test.entities.Animal; 

@Remote 
public interface MapBeanRemote { 

    public void addAnimal(Animal a); 

    public void removaAnimal(Integer id); 

    public Animal getAnimalById(Integer id); 

    Map<Integer, Animal> getAllAnimals(); 

} 

はセッションBeanです:

package com.test.beans; 

import java.util.ConcurrentHashMap; 
import java.util.Map; 

import javax.annotation.PostConstruct; 
import javax.ejb.Stateless; 

import com.test.entities.Animal; 

@Stateless(mappedName="ejb/MapBean") 
public class MapBean implements MapBeanRemote{ 

    Map<Integer, Animal> animalStore; 

    @PostConstruct 
    public void initialize(){ 
     animalStore = new ConcurrentHashMap<Integer,Animal>(); 
    } 

    @Override 
    public void addAnimal(Animal a) { 
     if(a.getId()!=null){ 
      animalStore.put(a.getId(), a); 
     } 
    } 

    @Override 
    public Animal getAnimalById(Integer id) { 
     return animalStore.get(id); 
    } 

    @Override 
    public void removaAnimal(Integer id) { 
     animalStore.remove(id); 

    } 

    @Override 
    public Map<Integer, Animal> getAllAnimals() { 
     return animalStore; 
    } 

} 
は、

だから基本的に私はtを操作したいクライアント彼はAnimal Mapを使ってこのEJBを調べ、各クライアントがオブジェクトの同じ正確なマップにアクセスするようにします。

この例は十分に機能しません。しばらくすると、すべての動物が消去されます(EJBがBeanプールから置き換えられると仮定しています)。これをリソースとして注入することはできますか?

答えて

3

これは、Mapをシングルトンに入れ、Beanからこのシングルトンにアクセスすることで実現できます。そうすれば、(同じクラスローダを共有するので)すべてのEJBインスタンスに対して1つのインスタンスが存在します。異なるEARのセッションBeanはそれぞれ独自のクラスローダーを持っているため動作しませんが、それはあなたのシナリオではありません。

既存のConcurrentHashMapを使用すると、大部分のケースを十分に処理できますが、addAnimalメソッドを同期させる必要があるのは、マップが2つのメソッド呼び出しの間で一貫している必要があるためです。

0

私は、EJBからデータ構造を完全に移動し、それを静的なデータ構造として保存するのが最善だと思います。 EJBがプールされているため、オブジェクトが消去されているという事実はおそらく正しいでしょう。

スレッドの安全性を保証するために多くの場合、アクセスを同期させる必要があるデータ構造へのアクセスを実装する方法によって異なります。

EJB内部で状態を維持する場合は、ステートフルセッションBeanを検討することを検討してください。また、あなたは豆を使用して、ejbRemoveメソッドをオーバーライドする可能性が破壊された時に見たいなかった場合、私は、Java 5のため

を注釈を忘れるカール

+0

ありがとうございました。ステートフルセッションBeanは、アプリケーションサーバー全体ではなく、特定のクライアントで状態を維持するためのものです。 – systemoutprintln

+0

はい、あなたの正しい、申し訳ありませんが明らかにしている必要があります。 – Karl

1

これは、ステートレスセッションBeanです。名前が示すように、あなたはそのようなbeanに状態を保持するべきではありません。 EJBコンテナは、同時リクエストを満たすためにBeanの複数のインスタンスで動作します。すべてのインスタンスのリストのデータをどのように同期させますか?私はこれを行う方法がないことです。

ビジネスロジックを証明したセッションBeanにそのようなリストを維持することは、私の意見ではビジネスレイヤーの概念に違反することさえあります。自分でトランザクションと同時書き込みを処理する必要があります。

なぜあなたはクライアント側で動物のリストを保持していませんか?私はこれがより良い方法だろう。

+0

私はビジネス層のコンセプトに違反することに同意します。そのため、理想的には、マップを何らかのリソースとして注入することができます。私は、Java SEアプリケーションをJava EEコンテキストにshoehorningしているので、サーバー側にMapを持たせる必要があります。 – systemoutprintln

+0

悪意:すべてのセッションBeanで使用される静的Mapを持つ静的クラスを使用し、マップの同期化がうまく実装され、作業を行うコンテナに影響を与えないことを願っています。 – Timo

2

新しいEJB 3.1仕様では、新しいタイプのBean(シングルトンBean)が提供されます。これはまさに必要なものです。私が知っているEJB 3.1を部分的にサポートしている唯一の実装は、Apache OpenEJB 3.1です。それはシングルトンの豆を含んでいますが、まだ使用していません。

関連する問題