Внедрение EntityManager приводит к исключению NullPointerException - PullRequest
3 голосов
/ 21 января 2010

Я пишу свое первое приложение Java EE (EJB + Servlets и т. Д.) (Обратите внимание: я использую Eclipse).
У меня возникла проблема с неработающим внедрением EntityManager, и у меня возникли некоторые трудности с поиском причин из-за моего неловкости в Java EE (и в целом в Java).

Вот мой persistence.xml файл - я думаю, что это в основном правильно, так как я могу запустить менеджер баз данных HSQL из консоли JMX, и моя таблица PUBLIC.USER отображается правильно.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="MyPu">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/DefaultDS</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

Вот мой код сервлета:

[...]
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws      
    String id = request.getParameter("username");
    String password = request.getParameter("password");

    UserManagerBean um = new UserManagerBean();
    um.register(username, password);

    RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("/index.jsp");
    dispatcher.forward(request, response);
}

А вот и мой класс UserManagerBean:

//bunch of imports

import myPackage.UserManager;

public @Stateful class UserManagerBean implements UserManager {
    @PersistenceContext(unitName="MyPu")
    private EntityManager persistManager;

    public void register(String username, String password) {
        User user = new User(userame, password);
        persistManager.persist(user);
        persistManager.flush();
    }
}

Строка persistManager.persist(user) создает исключение NullPointerException. Из моего собственного поиска я понял, что это происходит потому, что, поскольку я вызываю new () в UserManagerBean, инъекция из аннотации @PersistenceContext никогда не происходит, и persistManager никогда не связывается.
Если так, то очевидно, что я что-то упускаю из-за правильного использования EJB.
Как правильно создать экземпляр моего бина? Что с интерфейсами? Я не совсем уверен, должен ли мой бин быть с состоянием или без состояния: \

Дополнительная информация:
Я изменил код в своем сервлете, с

UserManagerBean um = new UserManagerBean();

до

@EJB
private UserManagerBean um;

в соответствующем месте. Теперь um является нулевым указателем.

Ответы [ 4 ]

2 голосов
/ 21 января 2010

Цитирование Ссылка на сессионные EJB3-компоненты от не-EJB3-компонентов из документации JBoss:

Сервер приложений JBoss 4.2.2 реализовал функциональность EJB3 с помощью контейнера EJB MBean, работающего в качестве плагина на сервере приложений JBoss. Это имело определенные последствия для разработки приложений.

Плагин EJB3 вставляет ссылки на EntityManager и ссылки @EJB из одного объекта EJB в другой. Однако эта поддержка ограничена EJB3 MBean и файлами JAR, которыми он управляет. Любые файлы JAR, загруженные из WAR (например, сервлеты, компоненты поддержки JSF и т. Д.), Не проходят эту обработку. Стандарт Java 5 Enterprise Edition указывает, что сервлет может ссылаться на сессионный компонент с помощью аннотированной ссылки @EJB, это не было реализовано в JBoss Application Server 4.2.2.

Так что, хотя спецификация Java EE 5 предусматривает более широкий охват аннотации @EJB, JBoss 4.2.2 не поддерживает ее. На самом деле JBoss 4.2.2 является переходной версией, которая не требует полного соответствия Java EE 5.

Следовательно, либо:

  • Придерживайтесь актуальной версии JBoss, но используйте поиск JDNI, чтобы получить свой бин - или -
  • Переход на JBoss 5 AS, который полностью поддерживает всю спецификацию Java 5 Enterprise Edition (но имеет ужасные характеристики при запуске) - или -
  • Перейдите на другой сервер приложений Java EE 5, например GlassFish v2 (или даже v3) или WebLogic 10. Я бы пошел с GFv3.
2 голосов
/ 21 января 2010

Как сказал Петр Минчев в комментариях выше, @EJB не работает в сервлетах с JBoss 4.2.

В вашей WAR (в каталоге WEB-INF) вам нужно изменить два файла:

web.xml:

<ejb-local-ref>
        <ejb-ref-name>ejb/UserManager</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home/>
        <local>myPackage.UserManager</local>
</ejb-local-ref> 

JBoss-web.xml:

<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
<jboss-web>

  <ejb-local-ref>
    <ejb-ref-name>ejb/UserManager</ejb-ref-name>
    <local-jndi-name>[earname]/UserManagerBean/local</local-jndi-name>
  </ejb-local-ref>

</jboss-web>

Затем вы можете получить экземпляр вашего EJB, выполнив:

UserManagerBean um = (UserManager)new InitialContext().lookup( "java:comp/env/ejb/UserManager" );
0 голосов
/ 06 марта 2016

Чтобы включить внедрение зависимостей в ваш проект, убедитесь, что у вас есть файл "beans.xml" и он правильно расположен.

  • Для WAR-упаковки: src / main / webapp / WEB-INF /
  • Для упаковки JAR и EAR указывается местоположение src / main / resources / META-INF /

Если у вас есть несколько модулей maven, они должны быть установлены на каждом модуле.

Дополнительная информация о beans.xml

0 голосов
/ 21 января 2010

Что касается комментариев, то получается, что вы действительно используете сервер приложений, который его вообще не поддерживает - как я и ожидал. Чтобы решить эту проблему, у вас есть 3 варианта:

  1. Использовать "старые добрые" файлы конфигурации XML.
  2. Обновление сервера (уже есть стабильная 5.1.0 ).
  3. Заменить сервер (я могу рекомендовать Glassfish v3 , чтобы быть самой современной ).
...