Recuperar EJB Stateful dentro de outro de Stateful - Problema

Boa noite pessoal,

Estou tentando recuperar um SB Stateful dentro de outro SB Stateful, so que ele está vindo nulo, ou seja, não está recuperando a instância existente, está criando outra pra mim.

Estou recuperando da seguinte maneira:


@Stateful
public class LogSistemaAcaoEjb implements Serializable {
   @EJB
    private LogSistemaEjb log;

  public void teste() throws NamingException {
        InitialContext tst = new InitialContext();
        log = (LogSistemaEjb) tst.lookup("java:global/AppEJBMoscaBrancaFinal/AppEJBMoscaBrancaFina/LogSistemaEjb!br.com.embrapa.moscabranca.controllerEjb.LogSistemaEjb");

        nome = log.getUsuario();
}

}

A minha classe LogSistemaEjb esta como @Stateful e @LocalBean para nao precisar implementar uma interface.
O lookup via JNDI esta funcionando, so que meu objeto esta nulo.

Agradeco quem puder me dar uma dica !!!

mas se você já anotou o log com @EJB, pra que o lookup?
Pra que 2 Statefuls? Já conversei com mais de 10 sêniors que utilizam ejb e nenhuma utilizou um Stateful se quer… você tem 2?! :shock: :shock: :shock: :shock: :shock:

Bom dia Frapout,

Não sei qual servidor está usando, mas no JBoss 7.0 faço o lookup da seguinte maneira:

	@SuppressWarnings("unchecked")
	public static <T> T getSessionBean(Class<T> t) throws Exception {
		try {
			String bean = "java:global/projectName/" + t.getSimpleName() + "!" + tpack.getName() +"." + t.getSimpleName();
			Context ctx = new InitialContext();
			return (T) ctx.lookup(bean);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

Com esse método faço lookup genérico, utilizo para recuperar qualquer EJB da minha aplicação.

Veja se funciona e posta aqui.

Oi,
quando vc faz…

InitialContext tst = new InitialContext();  
log = (LogSistemaEjb) tst.lookup("java:global/AppEJBMoscaBrancaFinal/AppEJBMoscaBrancaFina/LogSistemaEjb!br.com.embrapa.moscabranca.controllerEjb.LogSistemaEjb");

… vc cria uma outra sessão (outro cliente), então vc terá uma outra instancia do objeto “log”.

Veja esse exemplo. http://tomee.apache.org/examples-trunk/simple-stateful/. Ele mostra que o servidor cria uma nova instancia do objeto depois de um lookup.

[]s,
Thiago.

[quote=Hebert Coelho]mas se você já anotou o log com @EJB, pra que o lookup?
Pra que 2 Statefuls? Já conversei com mais de 10 sêniors que utilizam ejb e nenhuma utilizou um Stateful se quer… você tem 2?! :shock: :shock: :shock: :shock: :shock: [/quote]

Verdade, um Stateful ai pra te falar a verdade realmente esta passando por falta de atencao minha. Nao ha necessidade !! Nao consigo recuperar a instancia existente do EJB so anotanto ele com @EJB. Tem como Hebert ?
Pra te falar a verdade eu to quase desistindo do Stateful. Nao estou conseguindo ver utilidade, tendo em vista o que esta acontencendo.
Minha intencao e criar um objeto de log que teria data de entrada, usuario, hora de entrada e saida e um objeto para log de acoes. O log de acoes pode ser Stateless, mas meu log tem q ser Stateful. Independente de estar errado ai Hebert, o problema e a dificuldade em pegar o Stateful. Simplismente nao recupera com estado.
Eu to desistindo desse Stateful e vou jogar os dados que quero recuperar na sessao mesmo, aff !!!
Como vc disse ai, nem os experientes usam !!!

Ola guilherme_costa,
Estou usando o Glassfish. Nao funcionou. O nome JNDI e encontrado, e mesmo assim o objeto vem nulo.
No Jboss e ok ?

De qualquer forma valew pela forca !!

Olha ai !!! Afinal, Stateful tem ou nao tem utilidade ! Com tantas tentativas, estudando sobre e tentando varias formas, pedindo ajuda, e mesmo assim nao conseguindo ter exito em recuperar o bendito Stateful, vou ter que desistir desse safadinho !!

Valew Thiago !!

[quote=Frapout][quote=Hebert Coelho]mas se você já anotou o log com @EJB, pra que o lookup?
Pra que 2 Statefuls? Já conversei com mais de 10 sêniors que utilizam ejb e nenhuma utilizou um Stateful se quer… você tem 2?! :shock: :shock: :shock: :shock: :shock: [/quote]

Verdade, um Stateful ai pra te falar a verdade realmente esta passando por falta de atencao minha. Nao ha necessidade !! Nao consigo recuperar a instancia existente do EJB so anotanto ele com @EJB. Tem como Hebert ?
Pra te falar a verdade eu to quase desistindo do Stateful. Nao estou conseguindo ver utilidade, tendo em vista o que esta acontencendo.
Minha intencao e criar um objeto de log que teria data de entrada, usuario, hora de entrada e saida e um objeto para log de acoes. O log de acoes pode ser Stateless, mas meu log tem q ser Stateful. Independente de estar errado ai Hebert, o problema e a dificuldade em pegar o Stateful. Simplismente nao recupera com estado.
Eu to desistindo desse Stateful e vou jogar os dados que quero recuperar na sessao mesmo, aff !!!
Como vc disse ai, nem os experientes usam !!![/quote] Pelo que entendi você ainda não absorveu completamente o conceito do Stateful. O livro Enterprise JavaBeans 3.0 é muito bom e vale a pena.

Um @EJB apenas já deve injetar o EJB, não sei falar exatamente o que está errado aí com você.

[quote=Hebert Coelho][quote=Frapout][quote=Hebert Coelho]mas se você já anotou o log com @EJB, pra que o lookup?
Pra que 2 Statefuls? Já conversei com mais de 10 sêniors que utilizam ejb e nenhuma utilizou um Stateful se quer… você tem 2?! :shock: :shock: :shock: :shock: :shock: [/quote]

Verdade, um Stateful ai pra te falar a verdade realmente esta passando por falta de atencao minha. Nao ha necessidade !! Nao consigo recuperar a instancia existente do EJB so anotanto ele com @EJB. Tem como Hebert ?
Pra te falar a verdade eu to quase desistindo do Stateful. Nao estou conseguindo ver utilidade, tendo em vista o que esta acontencendo.
Minha intencao e criar um objeto de log que teria data de entrada, usuario, hora de entrada e saida e um objeto para log de acoes. O log de acoes pode ser Stateless, mas meu log tem q ser Stateful. Independente de estar errado ai Hebert, o problema e a dificuldade em pegar o Stateful. Simplismente nao recupera com estado.
Eu to desistindo desse Stateful e vou jogar os dados que quero recuperar na sessao mesmo, aff !!!
Como vc disse ai, nem os experientes usam !!![/quote] Pelo que entendi você ainda não absorveu completamente o conceito do Stateful. O livro Enterprise JavaBeans 3.0 é muito bom e vale a pena.

Um @EJB apenas já deve injetar o EJB, não sei falar exatamente o que está errado aí com você.[/quote]

Nao tem muito segredo. A minha classe que quero injetar tem que ser um EJB Stateful, no caso, e anotar o atributo que quero pegar esse EJB com @EJB na outra classe, onde desejo ter o meu EJB. A nao ser que tenha que configurar outros parametros.
Sim Hebert, meu conhecimento ainda nao e cem por cento. Valew pela dica, vou dar uma olhada nesse livro !!

Criei um exemplo de uso de stateful beans especialmente pra vc. :O)

https://github.com/tveronezi/stateful-stateless-integration

Neste exemplo eu uso um stateful pra compartilhar valores entre dois stateless. Este é um caso perfeito de uso do stateful.
Caso o stateful não existisse, eu teria que salvar o valor de “counter” em outro lugar, como uma DB por exemplo. Não preciso nem comparar
a performance de um stateful e um acesso ao banco de dados, né? :O)

@Stateful
public class StatefulBean {

    private int count = 0;

    public int count() {
        return count;
    }

    public int increment() {
        return ++count;
    }

}
@Stateless
public class StatelessBean {

    @EJB
    private StatefulBean counter;

    public int getNext() {
        return this.counter.increment();
    }

    public int getCurrent() {
        return this.counter.count();
    }

}
public class CounterTest extends TestCase {

    public void test() throws Exception {

        final Context context = EJBContainer.createEJBContainer().getContext();

        StatelessBean beanA = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");
        StatelessBean beanB = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");

        assertEquals(0, beanA.getCurrent());
        assertEquals(0, beanB.getCurrent());

        assertEquals(1, beanA.getNext());
        assertEquals(1, beanB.getCurrent());

        assertEquals(2, beanB.getNext());
        assertEquals(2, beanB.getCurrent());
    }

}

[quote=tveronezi]Criei um exemplo de uso de stateful beans especialmente pra vc. :O)

https://github.com/tveronezi/stateful-stateless-integration

Neste exemplo eu uso um stateful pra compartilhar valores entre dois stateless. Este é um caso perfeito de uso do stateful.
Caso o stateful não existisse, eu teria que salvar o valor de “counter” em outro lugar, como uma DB por exemplo. Não preciso nem comparar
a performance de um stateful e um acesso ao banco de dados, né? :O)

@Stateful
public class StatefulBean {

    private int count = 0;

    public int count() {
        return count;
    }

    public int increment() {
        return ++count;
    }

}
@Stateless
public class StatelessBean {

    @EJB
    private StatefulBean counter;

    public int getNext() {
        return this.counter.increment();
    }

    public int getCurrent() {
        return this.counter.count();
    }

}

[code]
public class CounterTest extends TestCase {

public void test() throws Exception {

    final Context context = EJBContainer.createEJBContainer().getContext();

    StatelessBean beanA = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");
    StatelessBean beanB = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");

    assertEquals(0, beanA.getCurrent());
    assertEquals(0, beanB.getCurrent());

    assertEquals(1, beanA.getNext());
    assertEquals(1, beanB.getCurrent());

    assertEquals(2, beanB.getNext());
    assertEquals(2, beanB.getCurrent());
}

}
[/code][/quote]Só tome cuidado. Nunca injete um Stateful dentro de um Stateless. Para cada Stateless criado, seria criado um Stateful mesmo que ñ fosse utilizado. E isso pode detonar a memória do servidor quanto maior fosse sua utilização.

É uma péssima prática que eu já vi descrita em quase (se não todos) os livros que já li.

Eu concordo com o Hebert nessa…

A verdade é que Stateful não escala muito bem, a minha opinião é que ele deve ser evitado.

Tem certeza que essa é a melhor maneira de fazer o que você quer?

Se alguem tem algum bom exemplo de Stateful na prática eu gostaria de ouvir, nos projetos que trabalhei não encontrei… sempre causou problemas

Só não me venha com a história do carrinho de compras :slight_smile:

[quote=tveronezi]Criei um exemplo de uso de stateful beans especialmente pra vc. :O)

https://github.com/tveronezi/stateful-stateless-integration

Neste exemplo eu uso um stateful pra compartilhar valores entre dois stateless. Este é um caso perfeito de uso do stateful.
Caso o stateful não existisse, eu teria que salvar o valor de “counter” em outro lugar, como uma DB por exemplo. Não preciso nem comparar
a performance de um stateful e um acesso ao banco de dados, né? :O)

@Stateful
public class StatefulBean {

    private int count = 0;

    public int count() {
        return count;
    }

    public int increment() {
        return ++count;
    }

}
@Stateless
public class StatelessBean {

    @EJB
    private StatefulBean counter;

    public int getNext() {
        return this.counter.increment();
    }

    public int getCurrent() {
        return this.counter.count();
    }

}

[code]
public class CounterTest extends TestCase {

public void test() throws Exception {

    final Context context = EJBContainer.createEJBContainer().getContext();

    StatelessBean beanA = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");
    StatelessBean beanB = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");

    assertEquals(0, beanA.getCurrent());
    assertEquals(0, beanB.getCurrent());

    assertEquals(1, beanA.getNext());
    assertEquals(1, beanB.getCurrent());

    assertEquals(2, beanB.getNext());
    assertEquals(2, beanB.getCurrent());
}

}
[/code][/quote]

Eu estava fazeendo dessa forma cara. Da um erro dizendo que o container nao foi encontrado.

javax.servlet.ServletException: javax.ejb.EJBException: No EJBContainer provider available: no provider names had been found

E tem a questao q o Hebert mencionou tambem. A criacao involuntaria do Stateful a cada Stateless pode ser fatal em caso de muitos acessos desta forma.

[quote=Hebert Coelho][quote=tveronezi]Criei um exemplo de uso de stateful beans especialmente pra vc. :O)

https://github.com/tveronezi/stateful-stateless-integration

Neste exemplo eu uso um stateful pra compartilhar valores entre dois stateless. Este é um caso perfeito de uso do stateful.
Caso o stateful não existisse, eu teria que salvar o valor de “counter” em outro lugar, como uma DB por exemplo. Não preciso nem comparar
a performance de um stateful e um acesso ao banco de dados, né? :O)

@Stateful
public class StatefulBean {

    private int count = 0;

    public int count() {
        return count;
    }

    public int increment() {
        return ++count;
    }

}
@Stateless
public class StatelessBean {

    @EJB
    private StatefulBean counter;

    public int getNext() {
        return this.counter.increment();
    }

    public int getCurrent() {
        return this.counter.count();
    }

}

[code]
public class CounterTest extends TestCase {

public void test() throws Exception {

    final Context context = EJBContainer.createEJBContainer().getContext();

    StatelessBean beanA = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");
    StatelessBean beanB = (StatelessBean) context.lookup("java:global/stateful-stateless-integration/StatelessBean");

    assertEquals(0, beanA.getCurrent());
    assertEquals(0, beanB.getCurrent());

    assertEquals(1, beanA.getNext());
    assertEquals(1, beanB.getCurrent());

    assertEquals(2, beanB.getNext());
    assertEquals(2, beanB.getCurrent());
}

}
[/code][/quote]Só tome cuidado. Nunca injete um Stateful dentro de um Stateless. Para cada Stateless criado, seria criado um Stateful mesmo que ñ fosse utilizado. E isso pode detonar a memória do servidor quanto maior fosse sua utilização.

É uma péssima prática que eu já vi descrita em quase (se não todos) os livros que já li.[/quote]

Concordo com voce Hebert. A criacao dos Statefuls seria involuntaria, e isso seria um problema !!!

Acabei de comprar o livro que me indicou Hebert ! Precisando me aprofundar mais em certos assuntos.