简体   繁体   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. 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. For this purposes I'm using the NetBeans 7 with GlassFish 3.1.为此,我将 NetBeans 7 与 GlassFish 3.1 一起使用。

{ApplicationName}-ejb: {应用程序名称}-ejb:

I've accomplished to generate entity classes from database and local sesssion beans for these entities.我已经完成了从这些实体的数据库和本地会话 bean生成实体类 Beans.xml is in place. Beans.xml就位。

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

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

I've created a simple POJO as a backing bean for the JSF page.我创建了一个简单的 POJO 作为 JSF 页面的支持 bean。 I've annotated it with javax.inject.@Named and javax.enterprise.context.@SessionScoped .我已经用javax.inject.@Namedjavax.enterprise.context.@SessionScoped对其进行了注释。 This backing bean is now accessible from the JSF page as well as being injected when the actual page is accessed.这个支持 bean 现在可以从 JSF 页面访问,并且在访问实际页面时被注入。 Beans.xml is in place as well. Beans.xml也已到位。

@Named
@SessionScoped
public class QuestBean implements Serializable {

    @EJB
    protected QuestFacade questFacade;

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

Having this deployed and page accessed, I'm, however, getting an error from GlassFish that the QuestFacade cannot be looked up by the JNDI.然而,在部署了这个并访问了页面后,我从 GlassFish 收到了一个错误,即 JNDI 无法查找QuestFacade

The stacktrace is quite long but the initial cause could be enough:堆栈跟踪很长,但最初的原因可能就足够了:

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

I understand that I'm persuading GlassFish to inject an EJB from a different module within the same application.我知道我正在说服 GlassFish 从同一应用程序中的不同模块注入 EJB。 Should the @Remote interface be used instead?应该改用@Remote接口吗? I've also tried to explicitely specify the name for both @Stateless and @EJB annotation but without any success.我还尝试明确指定@Stateless@EJB注释的名称,但没有任何成功。

I believe that I'm doing something fundamentaly wrong, but I cannot find out what.我相信我在做一些根本错误的事情,但我不知道是什么。

Any suggestion or would be greatly appreciated!任何建议或将不胜感激!

I believe that I'm doing something fundamentaly wrong, but I cannot find out what.我相信我在做一些根本错误的事情,但我不知道是什么。

What you're doing wrong is that if you implement a business interface (either @Local or @Remote ), then you must declare the variable where injection takes place as having the type of that interface, not of the actual bean class.你做错的是,如果你实现了一个业务接口( @Local@Remote ),那么你必须将发生注入的变量声明为具有该接口的类型,而不是实际的 bean class。

So in your case:所以在你的情况下:

@Named
@SessionScoped
public class QuestBean implements Serializable {

    @EJB
    protected QuestFacadeLocal questFacade;

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

However, a business interface is not required in EJB when you're doing local (in-jvm) communication.但是,当您进行本地(in-jvm)通信时,EJB 中不需要业务接口。 As you discovered, if you don't specify a business interface at all for your EJB, you can inject the bean class itself.正如您所发现的,如果您根本没有为您的 EJB 指定业务接口,您可以注入 bean class 本身。 This is because you then automatically get the so-called no-interface view .这是因为您随后会自动获得所谓的no-interface view

If you want, you can optionally declare that you want BOTH the local view and the no-interface view.如果你愿意,你可以选择声明你想要本地视图和无接口视图。 In that way, you can inject your bean class in places whether either the bean type itself is declared or its business interface.通过这种方式,您可以将 bean class 注入到任何位置,无论是声明了 bean 类型本身还是它的业务接口。 For this you use the @LocalBean .为此,您使用@LocalBean

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

Injection can thus happen in two ways now:因此,现在可以通过两种方式进行注入:

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

In practice I didn't found much use for having both methods available at the same time though, but maybe this adds to your understanding.在实践中,我发现同时使用这两种方法并没有多大用处,但也许这会增加你的理解。

Apparently the problem was that I generated @Local session beans.显然问题是我生成了@Local session bean。 Per this tutorial it is no longer necessary (?) to specify the @Local or @Remote interface.根据本教程,不再需要 (?) 指定@Local@Remote接口。 I still not completely understand the problem though.我仍然没有完全理解这个问题。

I Hope this answer could potentialy save up some time to somebody:-)我希望这个答案可以为某人节省一些时间:-)

Jarda雅尔达

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

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