Я считаю, что я делаю что-то в корне неправильно, но я не могу выяснить, что.
То, что вы делаете неправильно, заключается в том, что если вы реализуете бизнес-интерфейс (либо @Local
, либо @Remote
), то вы должны объявить переменную, в которой происходит внедрение, как тип этого интерфейса, а не фактического бобовый класс.
Итак, в вашем случае:
@Named
@SessionScoped
public class QuestBean implements Serializable {
@EJB
protected QuestFacadeLocal questFacade;
// several methods delegating lookups to the questFacade ...
}
Однако бизнес-интерфейс не требуется в EJB, когда вы выполняете локальную (in-jvm) связь. Как вы обнаружили, если вы вообще не указываете бизнес-интерфейс для своего EJB, вы можете внедрить сам класс bean-компонента. Это потому, что вы автоматически получаете так называемый no-interface view
.
Если вы хотите, вы можете опционально объявить, что хотите ОБА локального представления и представления без интерфейса. Таким образом, вы можете внедрить ваш класс bean-компонентов в местах, независимо от того, объявлен ли сам тип компонента или его бизнес-интерфейс. Для этого вы используете @LocalBean
.
@Stateless
@LocalBean
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal {
// some methods here as well as EntityManager injection ...
}
Впрыск теперь может происходить двумя способами:
@Named
@SessionScoped
public class QuestBean implements Serializable {
@EJB
protected QuestFacadeLocal questFacade; // possible because of local view
@EJB
protected QuestFacade questFacadeN; // possible because of no-interface view
// several methods delegating lookups to the questFacade ...
}
На практике я не нашел большого применения для одновременного использования обоих методов, но, возможно, это добавляет вам понимания.