Как использовать базу данных H2 с JPA в WebSphere Liberty

У меня есть очень простое веб-приложение, работающее на WebSphere Application Server 18.0.0.2. Приложение упаковано в WAR и помещено под dropins (для простоты).

Мой server.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">

    <featureManager>
        <feature>javaee-8.0</feature>
    </featureManager>

    <httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" />

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

    <!-- THE JAR IS THERE (UNDER Liberty lib directory) -->
    <library id="H2JDBCLib">
        <fileset dir="${wlp.install.dir}/lib" includes="h2-1.4.197.jar"/>
    </library>

    <!-- AND THIS IS MY DATA SOURCE DEFINITION -->
    <dataSource id="h2test" jndiName="jdbc/h2test">
        <jdbcDriver libraryRef="H2JDBCLib"/>
        <properties.db2.jcc databaseName="testdb" serverName="localhost" portNumber="8082" user="sa" />
    </dataSource>

</server>

У меня есть очень простая сущность и служба (без сохранения состояния EJB):

@Stateless
public class CustomerService {

    @PersistenceContext(unitName = "h2test")
    private EntityManager entityManager;

    public List<Customer> getAllCustomers() {
        return entityManager
                .createNamedQuery(FIND_ALL, Customer.class)
                .getResultList();
    }
}

А мой persistence.xml под META-INF выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
             version="1.0">

    <persistence-unit name="h2test" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

        <jta-data-source>jdbc/h2test</jta-data-source>

        <exclude-unlisted-classes>false</exclude-unlisted-classes>
    </persistence-unit>

</persistence>

Я думал, что этих простых конфигураций должно быть достаточно, чтобы иметь возможность развернуть и запустить это приложение типа «Hello World». Но я получаю ошибку во время выполнения:

[ERROR   ] CNTR0019E:  EJB throws an exception when invoking "getAllCustomers". 

    Details: javax.ejb.EJBException: The java:comp/env/com.my.app.service.CustomerService/entityManager reference of type javax.persistence.EntityManager for the null component in the my-app.war module of the my-app application cannot be resolved.
        at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1489)
        at [internal classes]
        at com.my.app.service.EJSLocalNSLCustomerService_22d8d9f5.getAllCustomers(EJSLocalNSLCustomerService_22d8d9f5.java)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)

Внедрение EntityManager завершается неудачно. Из документов IBM неясно, что еще нужно сделать.

У меня нет других файлов XML (файлов конфигурации) в моем приложении.

Я что-то упускаю ?


person ikos23    schedule 13.07.2018    source источник
comment
Не связано: в очереди на редактирование я наткнулся на вопрос, за который вы проголосовали в сортировке. Неправильный выбор. Пожалуйста: внимательно изучите справку по сортировке и не помещайте в очередь редактирования элементы, которые ей не принадлежат. (Я конкретно говорю о stackoverflow.com/review/triage/20888979). Пожалуйста, поймите, что ваши голоса имеют последствия!   -  person GhostCat    schedule 18.09.2018


Ответы (1)


Основная проблема, которую я вижу, это определение <datasource> в server.xml, вы использовали элемент <properties.db2.jcc>, который соответствует драйверу JDBC IBM DB2 JCC. Поскольку у Liberty нет специальной конфигурации <properties.h2>, вы должны использовать общий элемент конфигурации <properties>, а также определить имена классов DataSource для вашего элемента <jdbcDriver>.

Конфиг должен выглядеть примерно так:

<dataSource id="h2test" jndiName="jdbc/h2test">
    <!-- Define the DataSource class names on the <jdbcDriver> element -->
    <jdbcDriver 
        javax.sql.XADataSource="org.h2.jdbcx.JdbcDataSource"
        javax.sql.ConnectionPoolDataSource="org.h2.jdbcx.JdbcDataSource"
        javax.sql.DataSource="org.h2.jdbcx.JdbcDataSource" 
        libraryRef="H2JDBCLib"/>
    <!-- set the connection URL on the <properties> element.
         this corresponds to the setURL() method on H2's JdbcDataSource class.
         you may also list any properties here that have a corresponding setXXX method on H2's JdbcDataSource class -->
    <properties URL="jdbc:h2:mem:testdb"/>
</dataSource>

Кроме того, было бы лучше, если бы вы поместили драйвер JDBC H2 где-нибудь под ${server.config.dir} или ${shared.resource.dir}, поскольку ${wlp.install.dir}/lib — это место, где находятся jar-файлы среды выполнения Liberty. Вы не хотите смешивать свои банки приложений с ними!

<library id="H2JDBCLib">
    <fileset dir="${server.config.dir}" includes="h2-1.4.197.jar"/>
</library>

Наконец, убедитесь, что ваш файл persistence.xml находится в правильном месте в вашем приложении WAR. Это должно быть в WEB-INF/classes/META-INF/persistence.xml


В качестве промежуточного шага отладки вы можете убедиться, что DataSource разрешается из вашего приложения следующим образом:

@Resource(lookup = "jdbc/h2test")
DataSource ds;

// ...
ds.getConnection().close();

Как только эта часть заработает, переходите к инъекции EntityManager. Кроме того, не забудьте проверить ${server.config.dir}/logs/messages.log для получения более подробных сообщений об ошибках, если что-то пойдет не так.

person Andy Guibert    schedule 13.07.2018
comment
К вашему сведению, следующий выпуск Liberty (18.0.0.3) должен требовать меньше настроек при использовании базы данных H2. См.: github.com/OpenLiberty/open-liberty/pull/4276. - person Andy Guibert; 16.07.2018