EJB和存储数据结构中的对象(地图,列表等)

时间:2009-03-11 21:26:47

标签: java jboss java-ee ejb-3.0 ejb

在App Server的正常运行时间内,是否可以将对象存储在数据结构中?基本上我想要一个与这个数据结构接口的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;
    }

}

所以基本上我希望任何想要操作动物地图的客户通过这个EJB并让每个客户端访问相同的对象Map。

这个例子不够好。过了一会儿,所有的动物都被删除了(我假设当EJB从bean池中被替换时)这可能会以某种方式被注入资源吗?

4 个答案:

答案 0 :(得分:3)

这可以通过将Map放在Singleton中并从bean中访问这个单例来实现。这样,所有EJB实例都有一个实例(因为它们共享相同的类加载器)。不同EAR中的不同会话bean不会起作用,因为它们每个都有自己的类加载器,但这似乎不是你的场景。

您现有的ConcurrentHashMap用法将充分处理您的大部分情况,但您仍然需要围绕addAnimal方法进行同步,因为您需要两个方法调用之间的映射保持一致。

答案 1 :(得分:2)

新的EJB 3.1规范提供了新类型的bean - Singleton bean - 正是您所需要的。我知道的唯一支持EJB 3.1的实现是Apache OpenEJB 3.1。它包括Singleton bean但我尚未使用它们。

答案 2 :(得分:1)

这是一个无状态会话bean。顾名思义,你不应该在这样的bean中持有任何一种状态。 EJB容器可以与bean的多个实例一起使用以满足并发请求。如何同步所有实例列表的数据?我无法做到这一点。

将这样的List维护到会话bean中,这会提供业务逻辑,甚至违反了我认为的业务层的概念。您必须自己处理事务和并发写入。

为什么不在客户端持有动物清单?我认为这是更好的方式。

答案 3 :(得分:0)

我认为最好的想法是将数据结构完全移出EJB并将其存储为静态数据结构。

可能因为正在擦除您的对象这一事实,因此您可能是正确的。

注意,根据您实现数据结构访问的方式,您需要同步访问以确保线程安全。

如果要在EJB中维护状态,请考虑查看有状态会话bean。此外,如果您确实想要查看bean被销毁的时间,您可以覆盖ejbremove方法,我忘记了Java 5的注释。

卡尔