类型 [...] 的未满足依赖关系,在注入点使用限定符 [@Default](将 @Stateful EJB 与 CDI 结合使用)

2022-09-02 13:52:16

我有以下代码来管理两种存储库。这两个存储库类都继承一个接口以允许重新初始化其资源。

public interface CachingRepository
{
    public void invalidateCache();
}

全局、应用程序范围的存储库:

@Named("globalRepo")
@ApplicationScoped
public class GlobalRepository implements CachingRepository
{
    private List<Category> categories;

    ...

    @Override
    public void invalidateCache()
    {
        categories = null;
    }

    ...
}

每个用户,会话范围的存储库:

@Named("userRepo")
@SessionScoped
//@Stateful         // <- NOTE HERE
public class UserRepository implements CachingRepository, Serializable
{
    private List<MyFile> files;

    @Override
    public void invalidateCache()
    {
        files = null;
    }

    ...
}

将此(不带 )注入上下文时@Stateful

@Named
@ViewScoped
public class MyHandler implements Serializable
{
    @Inject
    private UserRepository userRepo;

    ...
}

它的工作原理。但是,在添加到类时,部署将失败,并出现异常,指出:@StatefulUserRepository

Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [UserRepository] with qualifiers [@Default] at injection point [[field] @Inject private de.company.project.pack.MyHandler.userRepo]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:275)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:244)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:107)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:127)
    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:346)
    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:331)
    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:366)
    at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:83)
    at org.jboss.as.weld.services.WeldService.start(WeldService.java:76)
    ... 5 more

添加 CDI 豆的名称,如

@Inject @Named("userRepo")
private UserRepository userRepo;

导致相同的异常。唯一可以结合使用的是使用 var 声明中的接口:@Stateful

@Inject @Named("userRepo")
private CachingRepository userRepo;

但是,我在这里可能需要子类功能,因此(目前)并不需要使用。CachingRepository

  1. 为什么这不能按预期工作?var 应该已经标识了要实例化的类,不是吗?这有什么逻辑呢?UserRepository
  2. 为什么 EJB 注释在这里有如此严重的影响?为什么它基本上迫使我在var声明中使用接口?@StatefulCachingRepository

请注意,我使用Seam 3 Faces使它成为CDI视图范围的Bean,所以手头的问题可能仍然只有CDI@ViewScoped


答案 1

我对这个误导性的例外有同样的问题...

通过添加,您可以公开接口的 EJB 方法,而无需声明无接口视图。添加到 以激活无界面视图。参见 EJB 3.1 规范, 第 4.9.8 节 “会话 Bean 的无接口视图”@StatefulUserRepositoryCachingRepository@LocalBeanUserRepository

Bean 类必须通过其 Bean 类定义或在部署描述符中指定它公开无接口视图。以下规则适用:

  • ...
  • 如果 Bean 至少公开了一个其他客户端视图,那么 Bean 会通过 bean 类或部署描述符上的@LocalBean注释来指定它公开无接口视图。
  • ...

我还参考了这个堆栈溢出答案,以获取有关无接口视图的更多信息。


答案 2

我遇到了同样的错误。

由以下原因引起:org.jboss.weld.exceptions.DeploymentException: WELD-001408:类型 UserTransaction @Default 的未满足依赖关系,在注入点 [BackedAnnotatedField] @Inject...

我像这样解决了这个问题:当我收到错误时,我以这种方式使用了UserTransaction。

@Inject
UserTransaction trans;

我没有使用 注释。@Inject@Resource


推荐