EJB и хранение объектов в структуре данных (карта, список и т. Д.) - PullRequest
1 голос
/ 12 марта 2009

Можно ли хранить объекты в структуре данных на время работы сервера приложений? По сути, я хочу 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 Remote :

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.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 и чтобы каждый клиент имел доступ к одной и той же карте объектов.

Этот пример не работает достаточно хорошо. Через некоторое время все животные будут стерты (я полагаю, когда EJB будет заменен из пула бинов). Может ли это быть каким-то образом внедрено как ресурс?

Ответы [ 4 ]

3 голосов
/ 12 марта 2009

Этого можно достичь, поместив карту в синглтон и получив доступ к этому синглтону из бобов. Таким образом, существует один экземпляр для всех экземпляров EJB (поскольку они совместно используют один и тот же загрузчик классов). Разные Session-бины в разных EAR не будут работать, так как у каждого будет свой загрузчик классов, но это не ваш сценарий.

Ваше существующее использование ConcurrentHashMap будет в достаточной степени обрабатывать большинство ваших случаев, но вам все еще нужна синхронизация вокруг метода addAnimal, поскольку вам нужно, чтобы карта была согласованной между двумя вызовами метода.

2 голосов
/ 23 марта 2009

Новая спецификация EJB 3.1 предоставляет новый тип bean-компонентов - Singleton-бины - именно то, что вам нужно. Единственная реализация с частичной поддержкой EJB 3.1, о которой я знаю, - это Apache OpenEJB 3.1. Он включает в себя бобы Singleton, но я их еще не использовал.

1 голос
/ 12 марта 2009

Это сессионный компонент без сохранения состояния. Как следует из названия, вы не должны иметь никакого состояния в таком бобе. Контейнер EJB может работать с несколькими экземплярами вашего компонента для удовлетворения одновременных запросов. Как вы синхронизируете данные списков всех экземпляров? Я думаю, что нет никакого способа сделать это.

Включение такого List в сессионный компонент, обеспечивающий бизнес-логику, на мой взгляд, даже нарушает концепцию бизнес-уровня. Вы должны позаботиться о транзакциях и одновременной записи самостоятельно.

Почему вы не держите Список животных на стороне клиента? Я думаю, что так будет лучше.

0 голосов
/ 12 марта 2009

Я думаю, что лучше всего было бы полностью удалить структуру данных из EJB и сохранить ее как статическую структуру данных. Вы, вероятно, правы в том, что ваши объекты стираются из-за объединения EJB-компонентов.

Обратите внимание, в зависимости от того, как вы реализуете доступ к структуре данных, вам нужно синхронизировать доступ для обеспечения безопасности потоков.

Если вы хотите поддерживать состояние внутри вашего EJB, тогда рассмотрите возможность просмотра сессионных компонентов с состоянием. Также, если вы хотите увидеть, когда бины уничтожаются, вы можете переопределить метод ejbremove, я забыл аннотацию для Java 5.

Karl

...