2011-12-24 28 views
16

que tiene un EJB (PersonManager) en el modulo de aplicaciones de empresa, que inyecta otra EJB (persona):JSF-bean gestionado EJB inyección

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

Quiero usar el PersonManager EJB en una aplicación web JSF. La defino en el 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> 

El problema es que, la inyección del PersonLocal EJB no sucede. La propiedad de la persona siempre es NULL. ¿Qué hice mal?

Pero si me inyecto la PersonManager en un grano de JSF logrado de esta manera:

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

funciona. Necesito la primera situación, ayúdeme por favor :-D

+0

Por qué no usas la anotación @EJB en lugar de declarar manualmente en faces-config.xml ?? Es como tratar de volver al pasado cuando la anotación no fue inventada: P –

+0

Tienes razón :-D es simplemente teórico, me gustaría saber la respuesta. – Forty

+0

@Forty Entonces, ¿por qué no funciona? La respuesta no está clara para mí. –

Respuesta

37

Está mezclando las responsabilidades de los EJB y los beans administrados JSF. El faces-config.xml registra solo artefactos JSF, como beans administrados y no EJB. Su inscripción en 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> 

básicamente hace exactamente lo mismo que

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

En otras palabras, se está registrando la clase como JSF bean gestionado que está disponible en las vistas por #{personManager}. Esto no representa la misma instancia que administra el contenedor EJB. Puede y debe no usar faces-config.xml para registrar EJB. Allí utiliza las anotaciones del paquete javax.ejb, como @Stateless y @Stateful. Eso es todo lo que necesita para registrar un EJB.

En realidad, el registro de beans administrados JSF en faces-config.xml es una antigua forma JSF 1.x que ha sido reemplazada en JSF 2.x por la nueva anotación @ManagedBean.


actualización el enfoque adecuado sería:

Vista (el archivo Facelets):

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

Controlador (JSF bean gestionado):

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

    // ... 
} 

Modelo (la entidad JPA):

@Entity 
public class Person implements Serializable { 

    @Id 
    private Long id; 

    private String name; 

    // ... 
} 

Servicio (EJB sin estado):

@Stateless 
public class PersonService { 

    @PersistenceContext 
    private EntityManager em; 

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

    // ... 
} 
+0

Gracias, el PersonManager es un EJB empresarial, por lo tanto, no contiene la anotación @ManagedBean. Es creado por el motor JSF, simplemente no inyecta a la persona EJB en él, bajo el escenario faces-config. – Forty

+0

Sé qué son los EJB y cómo se supone que deben usarse. ¿Vos si? ¿Qué parte exactamente ahora todavía no está claro? – BalusC

+4

Tenga en cuenta que falta el '@ Stateful' en mi ejemplo de respuesta. Es ** no ** un EJB de esta manera. Intentabas abusar del EJB como un frijol administrado JSF. Esto no está bien. Básicamente, debe tener 1 archivo XHTML como Ver, 1 Bean gestionado JSF como Controlador, 1 entidad como Modelo y 1 EJB como servicio. En su pregunta, el 'PersonManager' debe ser un bean gestionado JSF, no un EJB. El 'PersonLocal' parece demasiada entidad, no un EJB. Entonces dudo si realmente necesita ser un EJB. Los EJB están destinados a ofrecer servicios como 'create()', 'save()', etc. – BalusC