@Inject в базовом классе является нулевым в методах базового класса, хорошо в производном классе
В следующем коде я пытаюсь внедрить бин SessionScoped в EJB без сохранения состояния, но я хочу сделать @Inject в абстрактном базовом классе EJB. В соответствии со спецификацией CDI кажется, что это должно работать (никогда не тратить слова):
"4.2 Наследование метаданных на уровне членов
Предположим, что класс X прямо или косвенно расширен классом bean-компонента управляемого или сессионного компонента Y.
Если X объявляет введенное поле x, тогда Y наследует x."
Что происходит, так это то, что я могу получить доступ к унаследованному защищенному члену sessionView из TestEjb, но не из кода в базовом классе. Когда я говорю "могу получить доступ", я имею в виду, что введенный элемент доступен во время выполнения и не является нулевым.
@Named
@ViewAccessScoped
public class JsfBean extends implements Serializable {
@Inject private TestEjb ejb;
SessionView s1 = ejb.getSessionViewChild(); // sessionView injected ok
SessionView s2 = ejb.getSessionViewBase(); // sessionView is null
}
@Named
@SessionScoped
public class SessionView implements Serializable {}
@Stateless
public class TestEjb extends BaseClass implements Serializable {
public SessionView getSessionViewChild() {
return sessionView;
}
}
public abstract class BaseClass implements Serializable {
@Inject
protected SessionView sessionView;
public SessionView getSessionViewBase() {
return sessionView;
}
}
Что происходит, так это то, что s1 является допустимой ссылкой на SessionView, но s2 является нулевым.
Я использую MyFaces CODI 1.01 в сочетании с Weld из Glassfish 3.1.1. Я пытался удалить abstract из BaseClass и даже добавил @Named, но это не помогло, и я не вижу, что я делаю неправильно.
В нынешнем виде мне кажется, что мне придется наследовать sessionView от базового класса и передавать его обратно в качестве параметра методам из базового класса. Так что я буду благодарен, если кто-нибудь может указать, что я делаю что-то глупое, возможно, это проблема CODI/Weld?
Благодарю.
2 ответа
Это ошибка в Weld. Если он работает с другими областями, это ошибка в пользовательских областях в сочетании со сваркой.
Оказывается, мое понимание проблемы на момент публикации было основано на слишком ограниченном наборе наблюдений - все было неправильно. Оказывается, что реальная проблема заключалась в том, что я не смог успешно внедрить менеджер сущностей в ejb без состояния с помощью @PersistenceContext в перегруженном методе, который принимает параметр универсального типа. Эта проблема предположительно решена в Glassfish 3.1.2. Например:
@Stateless
public class Myejb<T> {
@PersistenceContext(unitName = "TestPU")
private EntityManager em;
public void find(String id) { em.find... }
public void find(T id) { em.find... }
em в find(T id) будет иметь значение null, и при использовании @EJB возникает та же проблема, что и при @PersistenceContext. На самом деле, очень важно!