对于没有接口视图的 bean,@EJB 注入在单例中失败

@EJB Injection fails in a singleton for a bean with no interface view

我有一个无接口视图的无状态 DAO-EJB,它是从通用抽象 DAO class 继承的,带有附加方法 readAll(); 所以树是 FooDAOBean <- extends GenericDAOImpl <- implements GenericDAOInterfaceclick here to see GenericDAO implementation - 在 link 中它不是摘要 class):

@Stateless
public class FooDAOBean extends GenericDAOImpl<ENodeFocus, Serializable>{

    @Override   
    public List<Foo> readAll() {
        // do something...
    }
}

我有一个初始化 bean,它应该使用一些条目配置应用程序:

@Singleton
@Startup
public class InitializationBean {

    @EJB
    FooDAOBean dao;

    @PostConstruct
    public void initialize() {
      // do something
    }
}

部署时出现错误:

WFLYNAM0059: Resource lookup for injection failed: env/shitstorm.beans.InitializationBean/dao

WFLYEE0046: Failed to instantiate component view

当我实现远程接口并使用 @Remote(<RemoteInterface>.class) 注释 FooDAOBean 时,它工作正常。但我不想允许远程访问。对我来说重要的是,FooDAOBean 的方法只能在同一个 JVM(本地)中访问。 FooDAOBeanInitializationBean 在同一个 EAR-Project 中,所以它应该可以工作,还是我错过了什么?它与单身人士有关还是这里发生了什么?我必须实现本地接口吗?我认为自 EJB 3.0 以来我不再需要它了。非常感谢! :)

请注意,您的 FooDAOBean 正在通过其超级 class 实现业务接口。

Oracle Java EE 教程指出:

If the bean class implements a single interface, that interface is assumed to the business interface. The business interface is a local interface unless it is annotated with the javax.ejb.Remote annotation; the javax.ejb.Local annotation is optional in this case.

因此您的 FooDAOBean 实际上有一个本地界面视图,而不是您期望的无界面视图。

我建议将您的 Bean 重命名为 FooDAOBeanImpl 之类的东西。然后创建一个继承自 GenericDAOInterface 的接口 FooDAOBean。现在让您的会话 Bean FooDAOBeanImpl 实现新接口,并用 @Local(FooDAOBean.class) 注释 class 以获得明确定义的 @Local 接口视图。现在您可以按预期注入 FooDAOBean