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