2009-03-11 6 views
1

Возможно ли иметь объекты, хранящиеся в структуре данных, на время работы сервера приложений? В принципе, я хочу, чтобы 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 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(); 

} 

Вот Session 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 будет заменен из пула бобов) Может ли это как-то быть введено в качестве ресурса?

ответ

3

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

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

0

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

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

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

Карла

+0

Спасибо. Готовность сеанса только для (как я понимаю) сохранения состояния с определенным клиентом, а не для всего сервера приложений. – systemoutprintln

+0

Да, ваше правильное, извините, должно было сделать это ясно. – Karl

1

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

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

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

+0

Я согласен с нарушением концепции бизнес-уровня. Вот почему, в идеале, я мог бы придать Карте какой-то ресурс. Мне нужна способность иметь карту на стороне сервера, потому что я запускаю приложение Java SE в контексте Java EE. – systemoutprintln

+0

Злая идея: используйте статический класс со статической картой, которая используется всеми сессионными компонентами, и надежная синхронизация карты хорошо реализована и не влияет на работу контейнера. – Timo

2

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

 Смежные вопросы

  • Нет связанных вопросов^_^