首页 > 解决方案 > 在类路径中找不到任何 META-INF/persistence.xml 文件,但我已经添加了它

问题描述

我正在尝试将 JPA 添加到我的项目中,但总是遇到这些错误:

keycloak_1   | 17:28:43,494 INFO  [org.hibernate.jpa.boot.internal.PersistenceXmlParser] (default task-2) HHH000318: Could not find any META-INF/persistence.xml file in the classpath
keycloak_1   | 17:28:43,495 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-2) Uncaught server error: javax.persistence.PersistenceException: No Persistence provider for EntityManager named SQL

但是当我尝试初始化我的实体管理器时:

HashMap<String, String> properties = new HashMap<>();
properties.put("javax.persistence.jdbc.driver", configMap.getFirst(CONFIG_KEY_JDBC_URL));
properties.put("javax.persistence.jdbc.url", configMap.getFirst(CONFIG_KEY_JDBC_URL));
properties.put("javax.persistence.jdbc.user", configMap.getFirst(CONFIG_KEY_DB_USERNAME));
properties.put("javax.persistence.jdbc.password", configMap.getFirst(CONFIG_KEY_DB_PASSWORD));

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(
        "SQL",
        properties
);

EntityManager entityManager = entityManagerFactory.createEntityManager();

我收到了这些错误,但我不明白这怎么可能,然后我清楚地将该文件添加到我的 .jar 中。

Persistence.xml 内容为:

<persistence 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"
             version="2.2">
    <persistence-unit name="SQL" transaction-type="RESOURCE_LOCAL">
        <properties>
            <property name="javax.persistence.jdbc.driver" value=""/>
            <property name="javax.persistence.jdbc.url" value=""/>
            <property name="javax.persistence.jdbc.user" value=""/>
            <property name="javax.persistence.jdbc.password" value=""/>
        </properties>
    </persistence-unit>
</persistence>

项目结构和编译后的 jar 在这里可见(持久化内容更改为前面提到的 2.2 版本):

在此处输入图像描述

我究竟做错了什么?

更新: 即使 find 命令返回该文件存在于正确的目录中:

➜  sql-sync-spi find . -type f -name "persistence.xml"
./build/resources/main/META-INF/persistence.xml
./src/main/resources/META-INF/persistence.xml

更多更新: 我尝试从另一个项目复制 persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
    <persistence-unit name="user-storage-jpa-example">
        <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>

        <class>org.keycloak.quickstart.storage.user.UserEntity</class>

        <properties>
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="false" />
        </properties>
    </persistence-unit>
</persistence>

在服务启动时,我收到了致命错误:

07:03:02,188 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "sql-sync-spi-1.0-SNAPSHOT.jar")]) - failure description: {
    "WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.jboss.datasources.ExampleDS1"],
    "WFLYCTL0180: Services with missing/unavailable dependencies" => [
        "jboss.persistenceunit.\"sql-sync-spi-1.0-SNAPSHOT.jar#sql\".__FIRST_PHASE__ is missing [jboss.naming.context.java.jboss.datasources.ExampleDS]",
        "jboss.persistenceunit.\"sql-sync-spi-1.0-SNAPSHOT.jar#sql\" is missing [jboss.naming.context.java.jboss.datasources.ExampleDS1]"
    ]
}

因此,至少项目的一部分肯定会看到 persistence.xml 文件并尝试读取它。然后我将 xml 更改回我的设置,我再次在启动时没有错误,但在实体管理器初始化尝试时类路径中再次不存在文件。

标签: javajpakeycloak

解决方案


这更像是一个评论而不是一个答案,因为评论部分没有足够的空间,而且我还没有验证任何这些。

首先,我会在您的 Keycloak 服务器上定义一个新的 DataSource。请参阅:关系数据库设置

您的依赖项部分build.gradle应该看起来有点类似于:

dependencies {
    compileOnly 'org.keycloak:keycloak-server-spi'
    compileOnly 'org.keycloak:keycloak-common'
    implementation 'org.apache.commons:commons-lang3:3.12.0'
    compileOnly 'org.hibernate.javax.persistance:hibernate-jpa-2.1-api:1.0.0.Final'
    compileOnly 'org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:1.0.0.Final'

    compileOnly platform('org.wildfly.bom:wildfly-javaee8:14.0.1.Final')
    compileOnly platform('org.keycloak.bom:keycloak-spi-bom:15.0.1')
}

persistence.xml应该改变,因为我们在 Keycloak 上定义了一个 DataSource:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    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_1.xsd">
    <persistence-unit name="yourDataSource">
        <jta-data-source>your_DS_name</jta-data-source>
        <!-- List your entities here. For example: -->
        <class>com.rmndbrvn.sqlsyncspi.UserEntity</class>
    </persistence-unit>
</persistence>

EntityManager然后,您可以像这样在代码中获取一个实例:

@PersistenceContext(unitName = "yourDataSource")
EntityManager em;

推荐阅读