实体管理器在尝试使用 JPA 连接到 Java 中的 Dockerised DB2 时为空,还使用 ​​Maven 和 Open Liberty

Entity Manager is null when trying to connect to Dockerised DB2 in Java using JPA, also using maven & Open Liberty

所以我正在开发一个 API 并尝试使用 JPA 实体管理器从 java 连接到本地 docker DB2 实例。 运行 Apache Maven 并获得构建成功后,我尝试从 Postman 发出 GET 请求来测试端点并从 DB2 获取所有用户的列表。我收到以下错误消息,指出实体管理器为空。我试过在线研究,但似乎找不到解决方案。 Dao class 与之前使用 Derby 而不是 DB2 的迭代相比几乎没有变化,并且运行良好。 我想知道哪里出了问题,需要更改什么,是否不需要。下面提供的是 xml 文件和包含实体管理器的 DAO java class。 DB2 的所有属性都是正确的,因为它们与我能够从 Eclipse 的数据库开发中进行的成功连接相比没有变化。当时使用的驱动程序是 db2jcc4,我认为它与据说用于 maven 依赖项的驱动程序不同,所以不确定这是否是一个问题。

邮递员:

Error 500: java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.createNamedQuery(String, java.lang.Class)" because "this.em" is null

专家:

[INFO] [ERROR ] CWWJP0015E: An error occurred in the org.eclipse.persistence.jpa.PersistenceProvider persistence provider when it attempted to create the container entity manager factory for the jpa-unit persistence unit. The following error occurred: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.EntityManagerSetupException

[INFO] Exception Description: Predeployment of PersistenceUnit [jpa-unit] failed.

[INFO] Internal Exception: javax.persistence.PersistenceException: CWWJP0013E: The server cannot locate the java:comp/DefaultDataSource data source for the jpa-unit persistence unit because it has encountered the following exception: javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:comp/DefaultDataSource.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  
  <groupId>com.obdoblock</groupId>
  <artifactId>hyperledger-api</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  
  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- Liberty configuration -->
        <liberty.var.default.http.port>3500</liberty.var.default.http.port>
        <liberty.var.default.https.port>9443</liberty.var.default.https.port>
        <liberty.var.app.context.root>api</liberty.var.app.context.root>
        <!-- TestDB Configuration -->
        <version.ibm.db2>11.5.6.0</version.ibm.db2>
    </properties>

    <dependencies>
        <!-- Provided dependencies -->
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-api</artifactId>
            <version>8.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.microprofile</groupId>
            <artifactId>microprofile</artifactId>
            <version>3.3</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>
        <!-- For tests -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.6.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.3.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.3.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>yasson</artifactId>
            <version>1.0.7</version>
            <scope>test</scope>
        </dependency>
        <!-- DB2 connector -->
        <dependency>
            <groupId>com.ibm.db2</groupId>
            <artifactId>jcc</artifactId>
            <version>11.5.6.0</version>
        </dependency>
        <!-- Hyperledger Fabric Gateway for Blockchain -->
        <dependency>
            <groupId>org.hyperledger.fabric</groupId>
            <artifactId>fabric-gateway-java</artifactId>
            <version>2.2.0</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <!-- Enable liberty-maven plugin -->
            <plugin>
                <groupId>io.openliberty.tools</groupId>
                <artifactId>liberty-maven-plugin</artifactId>
                <version>3.3.4</version>
                <configuration>
                    <copyDependencies>
                        <location>${project.build.directory}/liberty/wlp/usr/shared/resources</location>
                        <dependency>
                            <groupId>com.ibm.db2</groupId>
                            <artifactId>jcc</artifactId>
                            <version>11.5.6.0</version>
                        </dependency>
                    </copyDependencies>
                </configuration>
            </plugin>
            <!-- Plugin to run functional tests -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <systemPropertyVariables>
                        <http.port>${liberty.var.default.http.port}</http.port>
                        <context.root>${liberty.var.app.context.root}</context.root>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.3</version>
            </plugin>
            <!-- Plugin to run unit tests -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>
</project>

server.xml

<server description="Obdoblock REST Server">
    <featureManager>
        <feature>jaxrs-2.1</feature>
        <feature>openapi-3.1</feature>
        <feature>jpa-2.2</feature>
        <feature>cdi-2.0</feature>
    </featureManager>
  
    <httpEndpoint 
        httpPort="${default.http.port}" 
        httpsPort="${default.https.port}"
        id="defaultHttpEndpoint" 
        host="*" 
    />

    <webApplication 
        location="hyperledger-api.war" 
        contextRoot="${app.context.root}"
    />
    
    <!-- DB2 Library Configuration -->
    <library id="DB2JCCLib">
        <fileset dir="${shared.resource.dir}" includes="*.jar" />
    </library>
    
    
    <dataSource jndiName="jdbc/db2">
        <jdbcDriver libraryRef="jdbcLib"/>
        <properties
            databaseName="testdb"
            serverName="localhost" 
            portNumber="50000"
            user="****" password="****"
        />
    </dataSource>
</server>

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- TODO: This will have to be configured by ENV as well -->
<!-- https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/p_ddl_generation.htm -->
<persistence version="2.2"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
                        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="jpa-unit" transaction-type="JTA">
        <properties>
            <!-- Connection Specific -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect"/>

            <property name="javax.persistence.jdbc.driver" value="com.ibm.db2.jcc.DB2Driver" />
            <property name="javax.persistence.jdbc.url"    value="jdbc:db2://localhost:50000/testdb" />
            <property name="javax.persistence.jdbc.user" value="****" />
            <property name="javax.persistence.jdbc.password" value="****" />

            <property name="show_sql" value="true"/>
            <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

UserDao.java

package dao;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.enterprise.context.RequestScoped;
import models.*;

@RequestScoped
public class UserDao {
    
    @PersistenceContext(name = "jpa-unit")
    private EntityManager em;

    public void createUser(Users user){
        em.persist(user);
    }

    public Users readUser(int userId){
        return em.find(Users.class, userId);
    }

    public List<Users> readAllUsers(){
        return em.createNamedQuery("Users.findAll", Users.class).getResultList();
    }


    public void updateUser(Users user){
        em.merge(user);
    }

    public void deleteUser(Users userId){
        em.remove(userId);
    }

    public List<Users> findUser(String email){
        return em.createNamedQuery("Users.findUser", Users.class)
            .setParameter("email", email)
            .getResultList(); 
    }

    public void createHistory(History hist){
        em.persist(hist);
    }
    //wait this doesnt do anything? 
    public Users readHistory(int id){
        return em.find(Users.class, id);
    }

    public List<History> readAllHistory(){
        return em.createNamedQuery("History.findAll", History.class).getResultList();
    }

}

版本:

如果需要更多详细信息,我很乐意提供。 谢谢,迪伦

您的persistence.xml不正确。它应该指向 server.xml 中配置的数据源,而不是指定驱动程序属性。

像这样:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
                        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="jpa-unit" transaction-type="JTA">
        <jta-data-source>jdbc/guestbookDS</jta-data-source>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="create" />
            <property name="javax.persistence.schema-generation.create-database-schemas" value="true" />
            <property name="javax.persistence.schema-generation.scripts.action" value="create" />
            <property name="javax.persistence.schema-generation.scripts.create-target" value="create.ddl"/>  
<!--
            <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
            <property name="eclipselink.ddl-generation.output-mode" value="both" />
            -->
        </properties>
    </persistence-unit>
</persistence>


您可以在此处检查这个使用 JPA 和数据库的非常简单的 Liberty 项目 https://github.com/stocktrader-ops/db-sat-demo(它使用 PostgreSQL 而不是 DB2,但您应该只使用您的数据源设置)