2011-12-24 6 views
16

Ho un EJB (PersonManager) nella modul Enterprise Application, che inietta un altro EJB (Persona):JSF-bean gestito EJB iniezione

@Stateful 
public class PersonManager implements PersonManagerLocal { 
    @EJB 
    private PersonLocal person; 

    @Override 
    public void setPersonName(String name) { 
     person.setName(name); 
    } 

    @Override 
    public String getPersonName() { 
     return person.getName(); 
    } 
} 

voglio usare il PersonManager EJB in una web app JSF. Mi definisco in faces-config.xml:

<managed-bean> 
    <managed-bean-name>personManager</managed-bean-name> 
    <managed-bean-class>ejb.PersonManager</managed-bean-class> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

Il problema è che, l'iniezione della PersonLocal bean non avviene. La proprietà persona è sempre NULL. Cosa ho sbagliato?

Ma se io iniettare il PersonManager in un fagiolo JSF gestito in questo modo:

@ManagedBean 
@RequestScoped 
public class Index { 
    @EJB 
    private PersonManagerLocal personManager; 
    .... 

FUNZIONA. Ho bisogno del primo scenario, ti prego di aiutarmi :-D

+0

Perché non si usa @EJB annotazioni invece di manualmente dichiararlo in faces-config.xml ?? È come cercare di tornare al passato quando Annotation non è stato inventato: P –

+0

Hai ragione MrGreen è solo teorico, mi piacerebbe sapere la risposta. – Forty

+0

@Forty Allora perché non funziona? La risposta non mi è chiara. –

risposta

37

Stai mescolando le responsabilità degli EJB e dei bean gestiti da JSF. Lo faces-config.xml registra solo elementi JSF, come bean gestiti e non EJB. La tua iscrizione in faces-config.xml

<managed-bean> 
    <managed-bean-name>personManager</managed-bean-name> 
    <managed-bean-class>ejb.PersonManager</managed-bean-class> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

fondamentalmente fa esattamente la stessa

@ManagedBean 
@SessionScoped 
public class PersonManager { 
    // ... 
} 

In altre parole, si sta registrando la classe come JSF bean gestito che è disponibile in vista per #{personManager}. Questo non rappresenta la stessa istanza gestita dal contenitore EJB. È possibile e necessario non utilizzare faces-config.xml per registrare EJB. Qui si utilizzano le annotazioni del pacchetto javax.ejb per, ad esempio @Stateless e @Stateful. Questo è tutto ciò che serve per registrare un EJB.

In realtà, la registrazione di bean gestiti JSF in faces-config.xml è un vecchio modo JSF 1.x che in JSF 2.x è stato sostituito dalla nuova annotazione @ManagedBean.


Aggiornamento l'approccio corretto sarebbe:

View (il file Facelets):

<h:form> 
    <h:inputText value="#{personManager.person.name}" /> 
    ... 
    <h:commandButton value="Save" action="#{personManager.save}" /> 
    <h:messages /> 
</h:form> 

Controller (JSF bean gestito):

@ManagedBean 
@ViewScoped 
public class PersonManager implements Serializable { 

    private Person person; 

    @EJB 
    private PersonService personService; 

    @PostConstruct 
    public void init() { 
     person = new Person(); 
    } 

    public void save() { 
     personService.create(person); 
     FacesContext.getCurrentInstance().addMessage(null, 
      new FacesMessage("Person successfully created, new ID is " + person.getId())); 
    } 

    // ... 
} 

Modello (l'entità JPA):

@Entity 
public class Person implements Serializable { 

    @Id 
    private Long id; 

    private String name; 

    // ... 
} 

Service (l'EJB stateless):

@Stateless 
public class PersonService { 

    @PersistenceContext 
    private EntityManager em; 

    public void create(Person person) { 
     em.persist(person); 
    } 

    // ... 
} 
+0

Grazie, PersonManager è un EJB aziendale, quindi non contiene l'annotazione @ManagedBean. È creato dal motore JSF, ma non inserisce il bean EJB in esso, sotto lo scenario faces-config. – Forty

+0

So cosa sono gli EJB e come dovrebbero essere usati. Fai? Quale parte è esattamente ora ancora non chiara? – BalusC

+4

Si noti che nel mio esempio di risposta manca '@ Stateful'. È ** non ** un EJB in questo modo. Stavi tentando di utilizzare l'EJB come bean gestito da JSF. Questo non è giusto. In pratica dovresti avere 1 file XHTML come Visualizza, 1 bean gestito JSF come Controller, 1 entità come Modello e 1 EJB come servizio. Nella tua domanda, il 'PersonManager' dovrebbe essere un bean gestito JSF, non un EJB. Il 'PersonLocal' sembra troppo un'entità, non un EJB. Quindi dubito che davvero debba essere un EJB. Gli EJB sono concepiti per fornire servizi come 'create()', 'save()', ecc. – BalusC