EJB stateful

Oi pessoal, estou estudando EJB, já li vários materiais, mas não ficou bem claro ainda…
Pelo que entendi stateful guarda estado, sempre é falado no exemplo do carrinho de compras. Porem se busco o EJB remoto em dois métodos diferentes (dois lookup) o EJB não guarda o estado mesmo estando anotado com @Stateful. Entendi que tenho que guardar a referencia o primeiro lookup(primeiro método) para passar para o segundo metodo, dessa forma ele consegue guardar o estado. Mas a minha pergunta é: qual a vantagem? pq na verdade ele não esta guardando estado, eu estou simplesmente armazenando o objeto e passando para o segundo método…
Pode ser viagem minha, mas realmente não entendi. Alguém pode me dar uma força?
obrigada

A vantagem é que o processamento não fica na sua máquina, embora possa parecer.

O objeto mesmo está em outro lugar (como você disse, o lookup foi remoto). O EJB Stateful tem uma particularidade, onde é criado um para cada sessão (ou um por cliente, se ficar mais fácil de visualizar assim).

Enquanto o EJB estiver sendo utilizado, nenhum outro cliente pode utilizar aquele objeto específico (o que não acontece com SLSB).

Se você for usar EJB, tem que montar sua aplicação nessa arquitetura, faz o lookup do EJB, realiza todo o processamento (como se ele fosse um objeto local, essa é a ideia do negócio), e depois o libera.

Não precisa ficar fazendo lookup dele em todos os métodos, o fluxo tem que ser pensado.

Até onde consigo entender, a questão é diferente do que você está imaginando.
Lembre-se, cada vez que o teu aplicativo cliente chama o servidor, está realizando uma requisição (ou seja, se fosse num ambiente web, teríamos um novo request). Cada nova requisição cria uma nova instância do EJB, pois o container não irá se preocupar em tentar adivinhar ou pesquisar se o cliente que invoca aquele EJB específico já o fez antes e em que estado se encontra aquele EJB.

Até mesmo quando você trabalha num ambiente web, com JSF 2, por exemplo, o managedbean precisa ser SessionScoped.

Isso também me soava estranho, tendo em vista que manter o estado, passivar e reativar são palavras que nos remetem a:

  • O EJB sabe com quem está falando.
  • O EJB “dorme” quando não está em uso.
  • O EJB é “despertado” quando é invocado pelo cliente que anteriormente o criou.

De qualquer forma, eu vejo que se você precisa invocar métodos de um EJB repetidas vezes, por que irá “fechar” a conexão a cada vez que for invocar um método?

acho que entendi, o processamento é feito no servidor e não na maquina local, mas tenho que guardar umas instancia desse EJB neste processo, pois o container não sabe que esse EBJ foi chamado pelo mesmo processo antes, então se chamar pela segunda vez ele entende que é um novo.
Não é uma boa prática ficar dando um lookup do servidor mais de uma vez? o certo então é guardar ele mesmo?

Então teria que ser feito desta maneira?

MeuPrimeiroBeanRemote meuBean = (MeuPrimeiroBeanRemote) ic.lookup("helloworldEAR/MeuPrimeiroBean/remote");
primeiroMetodo(meuBean);
segundoMetodo(meuBean);

Se você cria um objeto novo, fica reinstanciando a cada método que precisa dele? Não. isso não faz sentido.

É isso mesmo que você disse, você faz o lookup, executa todo o processamento necessário, e depois libera o EJB.

Mas se eu fizer esse mesmo processo de guardar o EJB chamando um stateless não vai ter o mesmo comportamento, já que estou guardando o objeto?

O Stateless tem um ciclo de vida diferente, ele não mantem estado, ele recebe a requisição, processa e retorna, depois ele pode receber requisições de outro cliente, não tem nada que prende ele a um só cliente.

Você pode guardar a referência dele, não tem problema, mas isso não quer dizer que vai ser sempre o mesmo objeto que vai responder à sua requisição.

Por isso que é muito bom injetar os EJBs quando possível, é algo a menos pra você se preocupar.

Acho que finalmente entendi… uahua
o chamado ‘guardar estado’ do stateful quer dizer que ele vai manter os objetos dentro dele setados, somente para um cliente (vai ser fiel a esse cliente), quando eu chamar novamente pelo lookup vai entender que é outro cliente.
Já o stateless não tem um cliente fixo, mesmo eu armazenando ele, quando eu for chamar um método no servidor, ele pode ou não pegar a mesma referencia que eu tinha armazenado (stateless fica no pool, certo?)
Eu estava achando que armazenar estado seria guardar o estado do objeto “pra sempre” até alguém destruir ele, mas estava pensando errado…

[quote=giselezr]Acho que finalmente entendi… uahua
o chamado ‘guardar estado’ do stateful quer dizer que ele vai manter os objetos dentro dele setados, somente para um cliente (vai ser fiel a esse cliente), quando eu chamar novamente pelo lookup vai entender que é outro cliente.
Já o stateless não tem um cliente fixo, mesmo eu armazenando ele, quando eu for chamar um método no servidor, ele pode ou não pegar a mesma referencia que eu tinha armazenado (stateless fica no pool, certo?)
Eu estava achando que armazenar estado seria guardar o estado do objeto “pra sempre” até alguém destruir ele, mas estava pensando errado…
[/quote]
Quando comecei a estudar EJBs, tive a mesma sensação.
Agora, a analogia do fiel é bacana.
Stateful é fiel, stateless é promíscuo…

Bom, vamos lá.

O Stateful vai armazenar estado “Pra sempre” sim, até que alguém o limpe ou o destrua, ele é um objeto como outro qualquer, se ninguém altera o valor daquela variável, ela vai ficar lá.

Os EJBs Stateful também possuem um pool, assim como os Stateless, nisso eles são iguais, a diferença é que quando um EJB está atendendo um cliente, ele não irá processar requisições de outro, já o Stateless não é assim, ele é o famoso “pau pra toda obra”, o que vier primeiro ele processa e pronto.

Entendi.

Obrigada pessoal :smiley: :smiley: :smiley: