jpa - 如何在 WebSphere Liberty 上通过 JPA 使用 H2 数据库

标签 jpa jakarta-ee h2 websphere-liberty open-liberty

我有一个非常简单的 Web 应用程序在 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();
    }
}

而我在 META-INF 下的 persistence.xml 如下所示:

<?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 注入(inject)失败。从 IBM 的文档来看,还不清楚还应该做什么。

我的应用中没有其他 XML 文件(配置文件)。

我错过了什么吗?

最佳答案

我看到的主要问题是 <datasource> server.xml 中的定义,您使用了 <properties.db2.jcc>元素,对应于 IBM DB2 JCC JDBC 驱动程序。由于 Liberty 没有专用的 <properties.h2>配置,您必须使用通用 <properties>配置元素,以及在 <jdbcDriver> 上定义 DataSource 类名称元素。

配置应该是这样的:

<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>

此外,如果您将 H2 JDBC 驱动程序放在 ${server.config.dir} 下的某处会更好或 ${shared.resource.dir} , 自 ${wlp.install.dir}/lib是 Liberty 运行时的 jar 所在的位置。您不想将您的应用程序 jar 与那些混在一起!

<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


作为中间调试步骤,您可以检查以确保数据源可以从您的应用程序中解析,如下所示:

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

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

一旦你让那部分工作,继续注入(inject)你的 EntityManager .另外,一定要检查 ${server.config.dir}/logs/messages.log如果出现问题,可以获取更详细的错误消息。

关于jpa - 如何在 WebSphere Liberty 上通过 JPA 使用 H2 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51330870/

相关文章:

JAVA:如何从 web.xml 加载数据库 url?

java - 如何在 Eclipse 中附加 Java EE 的源代码?

java - 在 Java EE 应用程序的开发中使用 Docker

c# - 连接到H2数据库

database - 如何在playframework 2.0中配置FS数据库?

java - Hibernate调用违反协议(protocol)异常

mysql - 计算分页后的记录数

java - 用于数据传输对象 (DTO) 投影的 Hibernate 二级缓存

java - "non-managed"实用程序类的并发访问和扩展

java - H2选择: unexpected type 39 mapping