Variaveis de instancias em Session Beans (EJB)

5 respostas
renanreismartins

Bom dia Pessoal.

Tenho um Session Bean que é Stateless e a natureza do mesmo realmente é Stateless, pois fornece APENAS UM método publico.

Acontece que este metodo publico recebe um objeto (Nota) e entao realizo inumeras operações com esta nota, para isso faço chamadas a vários outros métodos privados.

Exemplificando:

@Stateless(mappedName = "ejb/WSNFP")
public class EmissorNota implements EmissorNotaLocal {

   public void importaNota(Nota nota) {
      this.fazOperacao1(nota);
   }


   private void fazOperacao1(Nota nota) {
      //faz algumas operacoes
      OutroObj outroObj = nota.getOutroObj();
      this.fazOperacao2(nota, outroObj);
   }


   private void fazOperacao2(Nota nota, OutroObj outroObj) {
   //faz algumas operacoes
   }

}

observem que por se tratar de um Session Bean Stateless preciso ficar passando os parametros necessarios de metodo a metodo (aqui estou passando apenas nota, mas existem outros metodos privados que passam mais parametros).

Ao meu ver alem de dificultar e muito a programação, passar esses parametros deixa o codigo menos OO.

minha solução para o problema foi colocar a Nota e os outros objetos que são parametros de varios outros metodos como atributo do Session Bean e “mata-los” no final do metodo publico. Como sabemos se deixarmos esses objetos como atributos do Session Bean outro cliente pode usa-los, porem como Session bean tem apenas um metodo publico sempre que o cliente fizer uma chamada estara passando o objeto em que ele quer que seja realizado o processamento.

Assim nao sera necessario ficar passando um monte de parametros, ja que estes serão atributos do Session bean. E nem terei problemas de outra pessoa acessar estes atributos com valores incorretos.

Exemplificando:

@Stateless(mappedName = "ejb/WSNFP")
public class EmissorNota implements EmissorNotaLocal {

   private Nota nota;
   private OutroObj outroObj

   public void importaNota(Nota nota) {
      this.fazOperacao1();
      this.nota = null;
   }


   private void fazOperacao1() {
    // faz algo, com THIS.NOTA
   //faz algumas operacoes
     this.fazOperacao2();
   }


   private void fazOperacao2() {
    // faz algo, com THIS.NOTA
    // faz algo, com THIS.OutroObj
   //faz algumas operacoes
   }

}

Alguem consegue enxergar problemas nessa abordagem ou sugerir algo melhor ?

obrigado

grande abrassss

5 Respostas

M

Sim…
Nada te garante que se vc tiver 1 session bean atendendo, vc terá um atendimento sempre serial… quero dizer que, já que seu session bean é stateless voce nao tem nenhuma garantia que o container nao irá fazer chamadas concorrentes nesse metodo de um mesmo objeto. Para isso foram feitos os Stateful que mantém estado.

Não vejo nada de mau em passar esse objeto por parametro de metodos private para você dar continuidade no seu processamento. Esses metodos private serão reutilizados em outro petodo publico? Talvez o problema seja que você está dividindo esta funcionalidade em metodos private sem necessidade. Não existe certo e errado nessa historia…

De qualquer forma, se quer algo mais proximo ainda de uma orientação a objetos use uma implementação focada em DDD(domain driven design)

renanreismartins

oi marcelux, obrigado

entendo que o container pode fazer chamadas concorrentes ao meu ejb.

mas o seguinte, dentro do metodo public faço chamadas apenas a outros metodos private, sendo assim, as chamadas aos outros metodos serao feitas pelo proprio session bean.

veja que o cliente do meu session bean chama apenas seu metodo publico, e o session bean por sua vez chama seus proprios metodos private, por isso a chamada é executada pelo mesmo bean. Correto ?

Sendo assim posso ter inumeras chamadas concorrentes…

o meu ejb realmente é stateless pois o cliente nao depende de “inumeras” chamadas a ele para realizar uma tarefa, é apenas uma chamada e pronto.

Compreendeu até aqui ?

estou dividindo “funcionalidades” em varios metodos por questao de organização. é terrivel ter um metodo que faz tudo, o metodo “sistema”.

ddd nao eh uma questao até esse ponto. vamos focar mesmo na abordagem do ejb.

grande abrasss

esmiralha

Renan,

não precisa elocubrar muito. Se o seu Bean é Stateless, ele não pode ter variáveis de instância a não ser que você goste de dor de cabeça.

Exemplo:

2 threads chamam o método público do seu Bean passando duas notas diferentes A e B.

o primeiro thread altera o valor de nota para A;

o segundo thread altera o valor de nota para B;

pronto, vc ja está ferrado porque o primeiro thread vai receber o valor referente a segunda nota.

esmiralha

Se você quer fazer OO, dê ao objeto Nota a responsabilidade de se calcular…

renanreismartins

Pessoal,

conforme o amigo marcelux citou entendi que podem haver chamadas concorrentes, porém, no post acima citei que por serem chamadas a metodos privados, viajei que não teria o problema de concorrencia. Engano meu, pois assim ele teria de atender um cliente por vez…

conforme o esmiralha citou nada impede de um cliente chamar o ejb passando uma notaA e no meio do processamento um segundo cliente chamar o ejb passando a notaB alterando assim o estado do meu atributo.

entendi oq vc quis dizer com deixar a nota se calcular, mas essas operações que estou realizando sao do ejb mesmo

mto obrigado pela explicação de vcs… perfeito

grande abrass pessoal

Criado 11 de novembro de 2010
Ultima resposta 12 de nov. de 2010
Respostas 5
Participantes 3