Как правильно внедрить EJB Stateless Session Bean в веб-модуль? - PullRequest
9 голосов
/ 08 июня 2011

Будучи совершенно новым для Java EE (но не для самой Java), я пытаюсь создать очень простое «Корпоративное приложение» с Hibernate в качестве поставщика JPA и JSF в качестве реальной структуры пользовательского интерфейса.Для этих целей я использую NetBeans 7 с GlassFish 3.1.

{ApplicationName} -ejb:

Я достиг создания классов сущностей из базы данных и локальные сессионные компоненты для этих объектов. Beans.xml на месте.

@Stateless
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal {
    // some methods here as well as EntityManager injection ...
}

{ApplicationName} -war:

Я создал простой POJO в качестве поддержкибин для страницы JSF.Я пометил это с javax.inject.@Named и javax.enterprise.context.@SessionScoped.Этот компонент поддержки теперь доступен со страницы JSF, а также внедряется при доступе к реальной странице. Beans.xml также на месте.

@Named
@SessionScoped
public class QuestBean implements Serializable {

    @EJB
    protected QuestFacade questFacade;

    // several methods delegating lookups to the questFacade ...
}

После развертывания и доступа к странице я получаю ошибку от GlassFish, что QuestFacade нельзя просмотретьJNDI.

Трассировка стека довольно длинная, но первоначальной причины может быть достаточно:

Caused by: javax.naming.NamingException: Lookup failed for 'model.session.QuestFacade#model.session.QuestFacade' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found]
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:173)
    ... 74 more
Caused by: javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found
    at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
    at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
    at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
    at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
    ... 78 more

Я понимаю, что я уговариваю GlassFish внедрить EJB из другого модуля внутрито же самое приложение.Должен ли вместо этого использоваться интерфейс @Remote?Я также попытался явно указать имя для аннотации @Stateless и @EJB, но безуспешно.

Я считаю, что я делаю что-то в корне неправильно, но не могу понять, что.

Любое предложение или будет принята с благодарностью!

Ответы [ 2 ]

11 голосов
/ 12 июня 2011

Я считаю, что я делаю что-то в корне неправильно, но я не могу выяснить, что.

То, что вы делаете неправильно, заключается в том, что если вы реализуете бизнес-интерфейс (либо @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 ...
}

На практике я не нашел большого применения для одновременного использования обоих методов, но, возможно, это добавляет вам понимания.

0 голосов
/ 08 июня 2011

Очевидно, проблема была в том, что я генерировал @Local сессионные компоненты.Для этого урока больше нет необходимости (?) Указывать интерфейс @Local или @Remote.Я до сих пор не до конца понимаю проблему.

Надеюсь, этот ответ может кому-нибудь сэкономить: -)

Jarda

...