简体   繁体   English

尝试使用 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

So I'm developing an API and I'm trying to connect to a local docker instance of DB2 from java using JPA entity manager.所以我正在开发一个 API,我正在尝试使用 JPA 实体管理器从 java 连接到 DB2 的本地 docker 实例。 After running Apache Maven and getting build success, I try a GET request from Postman to test an endpoint and get a list of all users from DB2.在运行 Apache Maven 并获得构建成功后,我尝试从 Postman 发出 GET 请求来测试端点并从 DB2 获取所有用户的列表。 I'm receiving the below error saying that entity manager is null.我收到以下错误,指出实体管理器为空。 I've tried researching online and can't seem to find the solution.我尝试过在线研究,但似乎无法找到解决方案。 The Dao class is virtually unchanged from a previous iteration that used Derby instead of DB2 and it worked fine. Dao 类与之前使用 Derby 而不是 DB2 的迭代相比几乎没有变化,并且运行良好。 I was wanting to know where I've gone wrong, what needs changing, and if anything is not needed.我想知道我哪里出错了,需要改变什么,是否不需要什么。 Provided below is the xml files and the DAO java class containing the entity manager.下面提供的是 xml 文件和包含实体管理器的 DAO java 类。 All properties for DB2 is correct as they're unchanged from a successful connection I was able to do from Eclipse's Database Development. DB2 的所有属性都是正确的,因为它们与我能够从 Eclipse 的数据库开发中完成的成功连接相比没有改变。 The driver used then was db2jcc4 which I think is different to the driver said to use for the maven dependency so not sure if that's an issue.当时使用的驱动程序是 db2jcc4,我认为它与据说用于 maven 依赖项的驱动程序不同,所以不确定这是否是一个问题。

Postman:邮差:

Error 500: java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.createNamedQuery(String, java.lang.Class)" because "this.em" is null错误 500:java.lang.NullPointerException:无法调用“javax.persistence.EntityManager.createNamedQuery(String, java.lang.Class)”,因为“this.em”为空

Maven:马文:

[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. [INFO] [ERROR ] CWWJP0015E: org.eclipse.persistence.jpa.PersistenceProvider 持久性提供程序尝试为 jpa-unit 持久性单元创建容器实体管理器工厂时发生错误。 The following error occurred: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.9.v20210604-2c549e2208): org.eclipse.persistence.exceptions.EntityManagerSetupException发生以下错误:异常 [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] 异常描述:PersistenceUnit [jpa-unit] 的预部署失败。

[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. [信息] 内部异常:javax.persistence.PersistenceException:CWWJP0013E:服务器找不到 jpa-unit 持久性单元的 java:comp/DefaultDataSource 数据源,因为它遇到以下异常:javax.naming.NameNotFoundException:javax.naming .NameNotFoundException: java:comp/DefaultDataSource。

pom.xml 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服务器.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();
    }

}

Versions:版本:

  • Docker: 20.10.8, build 3967b7d Docker:20.10.8,构建 3967b7d
  • DB2: ibm/db2 docker image version 11.5.6 DB2:ibm/db2 docker 映像版本 11.5.6
  • Maven: 3.8.3 Maven:3.8.3
  • Java: JDK 14.0.2 Java:JDK 14.0.2

If needing any more details, I'm happy to provide them.如果需要更多详细信息,我很乐意提供。 Thanks, Dylan谢谢,迪伦

Your persistence.xml is incorrect.您的persistence.xml不正确。 It should point to datasource configured in the server.xml , not specify driver properties.它应该指向server.xml配置的数据源,而不是指定驱动程序属性。

Like this:像这样:

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


You can check this very simple Liberty project which uses JPA and database here https://github.com/stocktrader-ops/db-sat-demo (it is using PostgreSQL instead of DB2, but you should just use your datasource setup)您可以在此处查看这个使用 JPA 和数据库的非常简单的 Liberty 项目https://github.com/stocktrader-ops/db-sat-demo (它使用 PostgreSQL 而不是 DB2,但您应该只使用您的数据源设置)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM