Неудовлетворенные зависимости для типа [] с квалификаторами [@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, например

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

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

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

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

Вопросы:

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

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


person Kawu    schedule 27.04.2012    source источник
comment
О, и, кстати, на этот вопрос, похоже, уже в какой-то степени был дан ответ здесь interfac" title="weld 001408 неудовлетворенные зависимости при внедрении ejbs, реализующих интерфейс">stackoverflow.com/questions/9038815/, но почему, если вы используете EJB, вы больше не можете использовать реализацию? Какая логика стоит за этим? Почему больше нельзя? Эта условность вроде бы существует, но зачем она вообще?   -  person Kawu    schedule 27.04.2012
comment
Как я уже писал, не вижу в этом смысла и рад, что это уже невозможно, так что с этим помочь не могу-)   -  person Petr Mensik    schedule 27.04.2012
comment
Знаете ли вы, что вам нужен @Named тогда и только тогда, когда вам нужен JSF-доступ для управляемого компонента CDI? Все, что он делает, это предоставляет квалифицированное EL-имя, он не создает pojo для управляемого компонента CDI (это "сделано" beans.xml)...   -  person jan groth    schedule 27.04.2012
comment
Да. :-) Репозитории отображаются как таблицы данных для выбора файлов, а bean-компоненты с областью просмотра в основном функционируют как обработчики загрузки/удаления файлов (запросы AJAX). Как только один файл добавляется или удаляется, список соответствующих файлов репо должен быть признан недействительным для повторного отображения. По крайней мере, это текущая идея.   -  person Kawu    schedule 27.04.2012


Ответы (5)


У меня была такая же проблема с этим вводящим в заблуждение исключением...

Добавляя @Stateful к UserRepository, вы раскрываете методы EJB интерфейса CachingRepository без объявления представления без интерфейса. Добавьте @LocalBean к UserRepository, чтобы активировать вид без интерфейса. См. спецификацию EJB 3.1, раздел 4.9.8 «Представление сеансового компонента без интерфейса».

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

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

Я также ссылаюсь на этот ответ stackoverflow для больше информации о представлениях без интерфейса.

person kraftan    schedule 30.04.2012
comment
У меня нет никакого EJB. Я даже не использую никаких аннотаций @Default в своем коде. Но все же во время запуска Wildfly выдает это исключение. Я много искал, но все говорят об EJB. - person Sujoy; 03.07.2017

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

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

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

@Inject
UserTransaction trans;

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

person Remziye Şahin    schedule 29.08.2019

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

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

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

@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"/>
person Sydney Molobela    schedule 07.05.2019

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

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

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

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

person hubert    schedule 21.05.2019
comment
О какой IDE вы говорите? Укажите контекст. - person nđq; 13.06.2019

Возможно, вам следует добавить непараметризованный конструктор в класс компонента. Я читал в документации Jboss, в которой говорится: конкретный класс Java, у которого есть конструктор без параметров (или конструктор, обозначенный аннотацией @Inject), является bean-компонентом.

person Ricky Benitez    schedule 06.04.2020
comment
Добро пожаловать в сообщество! Подобные предложения или частичные решения следует записывать в виде комментариев, а не ответов. Ответы следует писать только в том случае, если они содержат полные решения и отвечают на каждый вопрос ОП. - person tsvedas; 06.04.2020