Java EJB和在数据结构中存储对象(映射、列表等)

Java EJB和在数据结构中存储对象(映射、列表等),java,jboss,jakarta-ee,ejb-3.0,ejb,Java,Jboss,Jakarta Ee,Ejb 3.0,Ejb,在应用服务器正常运行期间,是否可以将对象存储在数据结构中?基本上,我想要一个与这个数据结构接口的EJB,但不需要一个成熟的数据库解决方案 作为示例,我制作了这个虚拟动物对象: package com.test.entities; public class Animal implements java.io.Serializable { private static final long serialVersionUID = 3621626745694501710L; priv

在应用服务器正常运行期间,是否可以将对象存储在数据结构中?基本上,我想要一个与这个数据结构接口的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();

}
package com.test.bean;
导入java.util.Map;
导入javax.ejb.Remote;
导入com.test.entities.Animal;
@遥远的
公共接口映射远程{
公共动物(动物a);
public void removaAnimal(整数id);
公共动物getAnimalById(整数id);
映射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;
    }

}
package com.test.bean;
导入java.util.ConcurrentHashMap;
导入java.util.Map;
导入javax.annotation.PostConstruct;
导入javax.ejb.Stateless;
导入com.test.entities.Animal;
@无状态(mappedName=“ejb/MapBean”)
公共类MapBean实现了MapBeanRemote{
地图动物商店;
@施工后
公共无效初始化(){
animalStore=新的ConcurrentHashMap();
}
@凌驾
公共动物(动物a){
如果(a.getId()!=null){
put(a.getId(),a);
}
}
@凌驾
公共动物getAnimalById(整数id){
返回animalStore.get(id);
}
@凌驾
public void removaAnimal(整数id){
动物商店。移除(id);
}
@凌驾
公共地图getAllAnimals(){
返回动物商店;
}
}
所以基本上,我希望任何想要操作动物映射的客户机都能通过这个EJB,让每个客户机访问相同的对象映射


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

我认为最好的办法是将数据结构完全移出EJB,并将其存储为静态数据结构。您可能是正确的,您的对象正在被擦除,因为EJB正在被池化

注意:根据您如何实现对数据结构的访问,您需要同步访问以确保线程安全

如果您想在EJB中保持状态,那么考虑查看有状态会话bean。另外,如果您确实希望看到bean何时被销毁,您可以重写ejbremove方法,我忘记了Java5的注释


Karl

我认为最好的办法是将数据结构完全移出EJB,并将其存储为静态数据结构。您可能是正确的,您的对象正在被擦除,因为EJB正在被池化

注意:根据您如何实现对数据结构的访问,您需要同步访问以确保线程安全

如果您想在EJB中保持状态,那么考虑查看有状态会话bean。另外,如果您确实希望看到bean何时被销毁,您可以重写ejbremove方法,我忘记了Java5的注释


Karl

这是一个无状态会话bean。顾名思义,您不应该在这样的bean中持有任何类型的状态。EJB容器可以与bean的多个实例一起工作以满足并发请求。如何同步所有实例列表的数据?我觉得没有办法这么做

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


你为什么不把动物名单放在客户端呢?我认为这是更好的方法。

这是一个无状态会话bean。顾名思义,您不应该在这样的bean中持有任何类型的状态。EJB容器可以与bean的多个实例一起工作以满足并发请求。如何同步所有实例列表的数据?我觉得没有办法这么做

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


你为什么不把动物名单放在客户端呢?我认为这是更好的方法。

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


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

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


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

新EJB3.1规范提供了新类型的bean—单例bean—这正是您所需要的。据我所知,唯一部分支持EJB3.1的实现是ApacheOpenEJB3.1。它包括单例bean,但我还没有使用它们。

新的EJB3.1规范提供了新类型的bean—单例bean—这正是您所需要的。唯一的实现