Неудовлетворительные зависимости для типа [...] с квалификаторами [@Default] в точке впрыска (с использованием @Stateful EJB с CDI)

У меня есть следующий код для управления двумя типами репозиториев. Оба класса репозитория наследуют интерфейс, позволяющий повторно инициализировать свои ресурсы.

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;

    ...
}

он работает. Однако при добавлении @Stateful в класс UserRepository развертывание завершается с исключением:

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 bean как

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

приводит к тому же исключению. Единственное, что работает в сочетании с @Stateful, - это использовать интерфейс в объявлении var:

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

Мне может понадобиться функция класса sub здесь, поэтому использовать CachingRepository на самом деле не нужно (на данный момент).

Q-х

  • Почему это не работает так, как ожидалось? UserRepository var должен уже определить, какой класс должен создаваться, не так ли? Какая логика для этого?
  • Почему аннотация @Stateful EJB имеет такие серьезные последствия здесь? Почему это существенно заставляет меня использовать интерфейс CachingRepository в объявлении var?

Примечание, я использую Seam 3 Faces, создавая @ViewScoped, как область видимости с ограниченным доступом CDI bean, поэтому проблема, вероятно, все еще CDI-only.

Ответ 1

У меня была такая же проблема с этим ошибочным исключением...

Добавив @Stateful в UserRepository, вы открываете EJB-методы интерфейса CachingRepository без объявления объявленного представления без интерфейса. Добавьте @LocalBean в UserRepository, чтобы активировать вид без интерфейса. См. EJB 3.1 Specification, раздел 4.9.8 "Session Bean No-Interface View"

Класс Bean должен обозначать, что он предоставляет представление без интерфейса через определение класса Bean или в дескрипторе развертывания. Применяются следующие правила:

  • ...
  • Если Bean предоставляет хотя бы один другой вид клиента, beanозначает, что он предоставляет вид без интерфейса посредством Аннотация @LocalBean в классе Bean или в развертывании дескриптор.
  • ...

Я также ссылаюсь на fooobar.com/questions/80383/... для получения дополнительной информации о представлениях без интерфейса.

Ответ 2

У меня такая же проблема.

И вот что я сделал, чтобы решить это:

Я должен был создать EJB, который я пытаюсь внедрить, как показано ниже, с контейнером с дикими цветами:

@ApplicationScoped
    public class Resources {
     private static final String DISCOUNT_SERVICE_ENDPOINT_PROPERTY =
        "services.discount.endpoint";
     private MyServiceImpl myService;
    }

@Produces
 public MyServiceImpl produceMyServiceImpl() {
     if (myService == null) {
         String endpoint = System.getProperty(DISCOUNT_SERVICE_ENDPOINT_PROPERTY);
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(MyServiceImpl.class);
        factory.setServiceName(MyService.SERVICE);
        factory.setAddress(endpoint);
        myService = (MyServiceImpl) factory.create();
     }
     return myService;

}

Ниже приведена конфигурация, которая находится в вашем файле standalone-full.xml.

<property name="services.discount.endpoint" value="http://localhost:8080/my_service/MyService/MyServiceImpl"/>

Ответ 3

У меня такая же проблема. Я надеюсь, что это может кому-то помочь.

Решить проблему:

  • Щелкните правой кнопкой мыши на projcet
  • Нажмите на Properties
  • найти Project facets
  • В Project facets активна опция CDI
  • Применить и сохранить.

Теперь все в порядке.

Ответ 4

У меня была такая же ошибка.

Вызывается: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Неудовлетворенные зависимости для типа UserTransaction с квалификаторами @По умолчанию в точке внедрения [BackedAnnotatedField] @Inject...

Я решил эту проблему так: Я использовал UserTransaction таким образом, когда получил ошибку.

@Inject
UserTransaction trans;

Вместо @Inject я использовал аннотацию @Resource.