繁体   English   中英

EJB Stateless Session Bean应该如何正确注入到web模块中?

[英]How should be EJB Stateless Session Bean correctly injected into the web module?

Being completely new to Java EE (but not to Java itself) I'm trying to build a very simple "Enterprise Application" with Hibernate as JPA provider and JSF as the actual UI framework. 为此,我将 NetBeans 7 与 GlassFish 3.1 一起使用。

{应用程序名称}-ejb:

我已经完成了从这些实体的数据库和本地会话 bean生成实体类 Beans.xml就位。

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

{应用程序名称}-战争:

我创建了一个简单的 POJO 作为 JSF 页面的支持 bean。 我已经用javax.inject.@Namedjavax.enterprise.context.@SessionScoped对其进行了注释。 这个支持 bean 现在可以从 JSF 页面访问,并且在访问实际页面时被注入。 Beans.xml也已到位。

@Named
@SessionScoped
public class QuestBean implements Serializable {

    @EJB
    protected QuestFacade questFacade;

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

然而,在部署了这个并访问了页面后,我从 GlassFish 收到了一个错误,即 JNDI 无法查找QuestFacade

堆栈跟踪很长,但最初的原因可能就足够了:

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

我知道我正在说服 GlassFish 从同一应用程序中的不同模块注入 EJB。 应该改用@Remote接口吗? 我还尝试明确指定@Stateless@EJB注释的名称,但没有任何成功。

我相信我在做一些根本错误的事情,但我不知道是什么。

任何建议或将不胜感激!

我相信我在做一些根本错误的事情,但我不知道是什么。

你做错的是,如果你实现了一个业务接口( @Local@Remote ),那么你必须将发生注入的变量声明为具有该接口的类型,而不是实际的 bean class。

所以在你的情况下:

@Named
@SessionScoped
public class QuestBean implements Serializable {

    @EJB
    protected QuestFacadeLocal questFacade;

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

但是,当您进行本地(in-jvm)通信时,EJB 中不需要业务接口。 正如您所发现的,如果您根本没有为您的 EJB 指定业务接口,您可以注入 bean class 本身。 这是因为您随后会自动获得所谓的no-interface view

如果你愿意,你可以选择声明你想要本地视图和无接口视图。 通过这种方式,您可以将 bean class 注入到任何位置,无论是声明了 bean 类型本身还是它的业务接口。 为此,您使用@LocalBean

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

因此,现在可以通过两种方式进行注入:

@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 ...
}

在实践中,我发现同时使用这两种方法并没有多大用处,但也许这会增加你的理解。

显然问题是我生成了@Local session bean。 根据本教程,不再需要 (?) 指定@Local@Remote接口。 我仍然没有完全理解这个问题。

我希望这个答案可以为某人节省一些时间:-)

雅尔达

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM