2012-01-03 15 views
8

Tengo un bean CDI @RequestScoped que quiero convertir en un EJB para obtener transacciones declarativas. (Estoy en EJB 3.1, Java EE 6)Estado de paso entre métodos EJB/@RequestScoped y @Stateless

Actualmente, estoy pasando el estado entre subrutinas, bajo el supuesto de que la instancia solo se utiliza en una sola solicitud. Si agrego @Stateless ahora esa suposición cambiaría.

Por ejemplo, quiero hacer algo como

@Stateless 
@Named 
@RequestScoped 
public class Foo { 
    private String var1; // can't use instance vars in @Stateless? 
    private String var2; 

    public void transactionForRequest() { 
    var1 = value; 
    var2 = value; 
    .... 
    subroutine(); 
    } 
} 

Asumo lo anterior no de obra es correcto?

estoy contemplando dos alternativas:

  • Uso @Stateful en lugar de @Stateless, junto con @Named y @RequestScoped.
  • Mantenga @Stateless y use el mapa EJBContext.getContextData para reemplazar variables de instancia.

Cual es mejor? ¿Y hay alguna otra alternativa en la que no estoy pensando? (Además de esperar a Java EE 7 o cambiar a Spring. :-))

+0

Uso de '@ Stateful' puede ser una habilidad-terminado. ¿Ha considerado usar el frijol normal sin estado y el frijol administrado '@ ConversationScoped' para pasar estados? –

+0

¿Cómo funcionaría esto? ¿Haría el EJB '@ Stateless' luego' @ Inject' un bean CDI? ¿Podría este CDI ser '@ RequestScoped'? – wrschneider

+0

Mantendría el bean como '@ Stateless' y usaré el bean' @ ConversationScoped' para pasar variables de páginas a páginas. Consulte este [artículo] (http://blog.goyello.com/2011/06/08/jee6-cdi-and-conversation-scope/) sobre cómo crear el asistente. –

Respuesta

12

Mientras @Stateless, @Singleton y @MessageDriven referencias se han de ámbito inyecta a través de @Inject, no pueden ser@RequestScoped o cualquier otro alcance Solo el modelo @Stateful es lo suficientemente flexible como para admitir ámbitos. En otras palabras, puede anotar la clase @Stateful frijol como @RequestScoped, @SessionScoped, etc ..

En términos simples @Stateless, @Singleton han fijado "alcances" ya. @Singleton es esencialmente @ApplicationScoped y @Stateless sería quizás un alcance inventado como @InvocationScoped, si eso existiera. El ciclo de vida de un bean @MessageDriven es responsabilidad exclusiva del Conector que lo impulsa y, por lo tanto, no se le permite tener un alcance definido por el usuario.

Ver también https://stackoverflow.com/a/8720148/190816

+0

David, solo para estar seguro: si tengo una referencia '@ RequestScoped' al EJB' @ Stateless', ¿qué me compra? Obtendré la misma referencia durante toda la solicitud, pero sigue siendo (probablemente) una referencia al proxy, por lo que cada vez que uso esta referencia, puedo finalizar en una instancia de EJB diferente. ¿Es esto correcto? –

+0

Exactamente. Para ponerlo en perspectiva, en OpenEJB solo creamos un proxy para cada bean sin estado y lo compartimos con toda la aplicación. Lo mismo para Singleton. En el caso de colocar RequestScoped (u otro ámbito) en un apátrida o Singleton, debe tratarse como un error en la implementación. Tendría que verificar dos veces la especificación y TCK sobre eso, pero esa es ciertamente la forma en que lo haría. Cualquier otra cosa es simplemente engañosa. –

+0

Gracias por aclarar David. Es solo otro momento en que la conexión entre EJB y CDI puede desorientar ... –

1

Si está utilizando beans sin estado, entonces usted es responsable de cualquier gestión de estado y normalmente lo haría en la capa de la aplicación web utilizando HttpSessions. Y sí, no puede usar variables de instancia ya que los beans sin estado se agrupan.

3

Me gustaría ir con SFSB en lugar de SLSB. Desea mantener un estado, por lo que para mí esta es la información más importante; este es un trabajo para Stateful EJB.

Además, no creo que EJBContext#getContextData() te ayude. Por lo que recuerdo, solo es válido para una duración de una llamada. Por lo tanto, cada invocación de un método en el EJB crear nuevo mapa de datos de contexto (por lo menos es lo que se esperaría.)

+0

Me alegra escuchar que @Stateful + @RequestScoped funcionaría, por cualquier razón, "stateful bean de sesión" todavía suena como una palabra sucia, pero "session-scoped session bean" suena mucho mejor. También - 'EJBContext # getContextData()' funciona bien para mí en esta situación porque la subrutina es una llamada a un método local ('this.subroutine()') en lugar de una invocación EJB. – wrschneider

+0

Tiene razón, si su llamada local está bien que los datos de contexto. Pensé que había inyectado su EJB ('@ EJB' o' @ Inject') e invocó varios métodos en la instancia de proxy. –

Cuestiones relacionadas