2012-01-03 11 views
8

Ho un bean CDI @RequestScoped che voglio trasformare in un EJB per ottenere transazioni dichiarative. (Sono su EJB 3.1, Java EE 6)Stato di passaggio tra i metodi EJB/@RequestScoped e @Stateless

Attualmente sto passando lo stato tra le subroutine, supponendo che l'istanza sia utilizzata solo in una singola richiesta. Se aggiungo @Stateless ora quell'ipotesi cambierebbe.

Ad esempio, voglio fare qualcosa di simile

@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(); 
    } 
} 

Suppongo che il sopra non lavoro-è corretto?

Sto contemplando due alternative:

  • Uso @Stateful invece di @Stateless, insieme con @Named e @RequestScoped.
  • Mantieni @Stateless e utilizza la mappa EJBContext.getContextData per sostituire le variabili di istanza.

Quale è meglio? E c'è qualche altra alternativa a cui non sto pensando? (Oltre ad aspettare Java EE 7 o passare a Spring. :-))

+0

Usando '@ Stateful' può essere un eccesso di abilità. Hai preso in considerazione l'utilizzo del bean Stateless normale e del bean gestito '@ ConversationScoped' per passare gli stati? –

+0

come funzionerebbe? Renderebbe EJB '@ Stateless' quindi' @ Inject' un bean CDI? Questo bean CDI potrebbe essere '@ RequestScoped'? – wrschneider

+0

Manterrei il bean come '@ Stateless' e useremo il bean' @ ConversationScoped' per passare variabili da pagine a pagine. Dai un'occhiata a questo [articolo] (http://blog.goyello.com/2011/06/08/jee6-cdi-and-conversation-scope/) sulla creazione guidata. –

risposta

12

Mentre @Stateless, @Singleton e @MessageDriven riferimenti possono avere con ambito iniettato attraverso @Inject, non possono essere@RequestScoped o qualsiasi altro scopo. Solo il modello @Stateful è abbastanza flessibile da supportare gli ambiti. In altre parole, è possibile annotare la classe @Stateful bean stessa come @RequestScoped, @SessionScoped, ecc ..

In termini semplici @Stateless, @Singleton hanno fissato "ambiti" già. @Singleton è essenzialmente @ApplicationScoped e @Stateless potrebbe essere uno scope pronto come @InvocationScoped, se esistente. Il ciclo di vita di un bean @MessageDriven dipende interamente dal Connector che lo guida e, pertanto, non può disporre di un ambito definito dall'utente.

Vedi anche https://stackoverflow.com/a/8720148/190816

+0

David, tanto per essere sicuro - Se ho il riferimento '@ RequestScoped' a EJB' @ Stateless' - cosa mi compra? Riceverò lo stesso riferimento durante l'intera richiesta, ma è ancora (probabilmente) un riferimento al proxy, quindi ogni volta che utilizzo questo riferimento, posso terminare con un'istanza EJB diversa. È corretto? –

+0

Esattamente. Per dirla in prospettiva, in OpenEJB creiamo solo un proxy per ogni bean Stateless e condividiamo con l'intera app. Lo stesso per Singleton. Nel caso di mettere RequestScoped (o altro scope) su un Stateless o Singleton, dovrebbe essere trattato come un errore nella distribuzione. Dovrei ricontrollare le specifiche e TCK su questo, ma questo è certamente il modo in cui lo farei. Qualcos'altro è fuorviante. –

+0

Grazie per il chiarimento David. E 'solo un altro momento in cui la connessione tra EJB e CDI può essere disorientante ... –

1

Se si utilizzano i fagioli stateless, si è responsabili di qualsiasi gestione dello stato e normalmente lo si farebbe nel livello dell'applicazione Web utilizzando HttpSession. E sì, non è possibile utilizzare le variabili di istanza come pool di bean privi di stato.

3

Vorrei andare con SFSB anziché SLSB. Vuoi tenere uno stato, quindi per me questa è l'informazione più importante - questo è un lavoro per Stateful EJB.

Inoltre, non credo che lo EJBContext#getContextData() ti possa aiutare. Per quanto mi ricordo, è valido solo per una durata di una chiamata. Pertanto, ogni invocazione di un metodo sul bean creerà nuova mappa dei dati di contesto (almeno è quello che mi aspettavo.)

+0

Felice di sentire @Stateful + @RequestScoped potrebbe funzionare - per qualsiasi ragione, "bean di sessione stateful" sembra ancora una parolaccia, ma "session session scope bean" suona molto meglio. Inoltre - 'EJBContext # getContextData()' funziona bene per me in questa situazione perché la subroutine è una chiamata al metodo locale ('this.subroutine()') piuttosto che una chiamata EJB. – wrschneider

+0

Hai ragione - se la sua chiamata locale di dati di contesto va bene. Ho pensato di aver iniettato il tuo EJB ('@ EJB' o' @ Inject') e invocato diversi metodi sull'istanza proxy. –

Problemi correlati