2011-06-08 13 views
9

Al ser completamente nuevo en Java EE (pero no en Java en sí), intento crear una "Aplicación empresarial" muy simple con Hibernate como proveedor JPA y JSF como el marco de la interfaz de usuario real. Para este propósito estoy usando NetBeans 7 con GlassFish 3.1.¿Cómo debería ser EJB Stateless Session Bean correctamente inyectado en el módulo web?

{} ApplicationName -ejb:

que he logrado generar clases de entidad de base de datos ygranos sesssion locales para estas entidades. Beans.xml está en su lugar.

@Stateless 
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal { 
    // some methods here as well as EntityManager injection ... 
} 

{} ApplicationName -Guerra:

He creado un POJO simple como un bean de respaldo para la página JSF. Lo he anotado con [email protected] y [email protected]. Ahora se puede acceder a este bean de respaldo desde la página JSF y también se puede inyectar cuando se accede a la página real. Beans.xml está en su lugar también.

@Named 
@SessionScoped 
public class QuestBean implements Serializable { 

    @EJB 
    protected QuestFacade questFacade; 

    // several methods delegating lookups to the questFacade ... 
} 

Después de haber desplegado esta página y acceder, soy, sin embargo, conseguir un error de GlassFish que el QuestFacade no se puede buscar por el JNDI.

El StackTrace es bastante largo, pero la causa inicial podría ser suficiente:

Caused by: javax.naming.NamingException: Lookup failed for 'model.session.QuestFacade#model.session.QuestFacade' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found] 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455) 
    at javax.naming.InitialContext.lookup(InitialContext.java:392) 
    at javax.naming.InitialContext.lookup(InitialContext.java:392) 
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:173) 
    ... 74 more 
Caused by: javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found 
    at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248) 
    at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215) 
    at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77) 
    at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505) 
    ... 78 more 

entiendo que estoy persuadir GlassFish para inyectar un EJB a partir de un módulo diferente dentro de la misma aplicación. ¿Debería usarse en su lugar la interfaz @Remote? También traté de especificar explícitamente el nombre para las anotaciones @Stateless y @EJB, pero sin éxito.

Creo que estoy haciendo algo fundamentalmente malo, pero no puedo averiguar qué.

Cualquier sugerencia o sería muy apreciada!

Respuesta

11

Creo que estoy haciendo algo fundamentaly mal, pero no puedo averiguar qué.

Lo que está haciendo mal es que si se implementa una interfaz de negocio (ya sea @Local o @Remote), entonces debe declarar la variable donde la inyección se lleva a cabo como tener el tipo de esa interfaz, no del grano real clase.

Así, en su caso:

@Named 
@SessionScoped 
public class QuestBean implements Serializable { 

    @EJB 
    protected QuestFacadeLocal questFacade; 

    // several methods delegating lookups to the questFacade ... 
} 

Sin embargo, una interfaz de negocio no es necesario en EJB cuando estás haciendo la comunicación local (en-JVM). Como descubriste, si no especificas una interfaz comercial para tu EJB, puedes inyectar la clase de bean. Esto se debe a que automáticamente obtienes el llamado no-interface view.

Si lo desea, puede declarar que desea TANTO la vista local como la sin interfaz. De esta forma, puede inyectar su clase de bean en lugares ya sea que se declare el tipo de bean o su interfaz de negocios. Para esto, usa el @LocalBean.

@Stateless 
@LocalBean 
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal { 
    // some methods here as well as EntityManager injection ... 
} 

inyección puede pues suceder de dos maneras: ahora

@Named 
@SessionScoped 
public class QuestBean implements Serializable { 

    @EJB 
    protected QuestFacadeLocal questFacade; // possible because of local view 
    @EJB 
    protected QuestFacade questFacadeN; // possible because of no-interface view 

    // several methods delegating lookups to the questFacade ... 
} 

En la práctica no me encontré mucho uso para tener ambos métodos disponibles al mismo tiempo, sin embargo, pero tal vez esto se suma a su comprensión .

+0

Aunque me las arreglé para ayudarme a mí mismo, como señalé en mi respuesta, considero que su respuesta es mejor ya que proporciona una explicación por qué no. ¡Gracias! – merxbj

+0

Wow. ¡Solo preciso! – kuhajeyan

0

Aparentemente el problema fue que generé @Local beans de sesión. Por this tutorial ya no es necesario (?) Especificar la interfaz @Local o @Remote. Todavía no entiendo completamente el problema sin embargo.

espero que esta respuesta podría potentialy ahorrar algo de tiempo para que alguien :-)

Jarda

Cuestiones relacionadas