You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ktor中JPA连接MongoDB报错:找不到Mdb的EntityManager持久化提供者

Ktor中JPA连接MongoDB报错:No Persistence provider for EntityManager named Mdb

我在Ktor应用里搭建同时访问MySQL和MongoDB的JPA环境,MySQL部分正常,但MongoDB连接失败,报错jakarta.persistence.PersistenceException: No Persistence provider for EntityManager named Mdb,系统检测不到MongoDB的持久化提供者。相关文件如下:

persistence.xml文件(路径:/Kotlin/JPA/src/main/resources/META-INF/persistence.xml)

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

<!--    <persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence">-->

<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_2_0.xsd"
             version="2.0">

        <persistence-unit name="pu">
            <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>


            <class>com.example.data.Student</class>

            <properties>
                <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>

                <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Students"/>
                <property name="jakarta.persistence.jdbc.user" value="root"/>
                <property name="jakarta.persistence.jdbc.password" value="mynewpassword"/>
            </properties>
        </persistence-unit>

<persistence-unit name="Mdb" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

    <class>com.example.data.Student</class>

    <properties>

        <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
        <property name="hibernate.ogm.datastore.host" value="localhost:27017"/>
        <property name="hibernate.ogm.datastore.database" value="databasename"/>
        <property name="hibernate.ogm.datastore.create_database" value="true"/>

    </properties>

</persistence-unit>

    </persistence>

Routing.kt文件(路径:plugins目录下)

fun Application.configureRouting() {
        install(ContentNegotiation) {
            json()
    }

    routing {
        get("/") {
            call.respondText("Hello World!")
        }

        get("/jpa") {
            val a =  Student(3, "George", "Python")

      val emf: EntityManagerFactory = Persistence.createEntityManagerFactory("Mdb")
            val em: EntityManager = emf.createEntityManager()

            em.transaction.begin()
            em.persist(a)
            em.transaction.commit()
            println(a)

            call.respond(HttpStatusCode.OK, "Working")
        }
    }
}

实体类Student.kt

package com.example.data

import jakarta.persistence.Entity
import jakarta.persistence.Id

@Entity
class Student(
    @Id
    val id: Int,
    val name: String,
    val tech: String
)

build.gradle.kts文件

val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project

dependencies {
    implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-locations-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version")
    implementation("io.ktor:ktor-serialization-jackson-jvm:$ktor_version")
    implementation("io.ktor:ktor-serialization-gson-jvm:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
    implementation("ch.qos.logback:logback-classic:$logback_version")
    testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
    implementation("org.jetbrains.kotlin:kotlin-maven-plugin:1.2.30")
    implementation("org.jetbrains.kotlin:kotlin-maven-noarg:1.2.30")
    implementation("org.hibernate:hibernate-core:6.1.0.Final")
    implementation("org.jetbrains.exposed:exposed-dao:0.38.2")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.38.2")
    implementation("org.ktorm:ktorm-core:3.5.0")
     implementation("mysql:mysql-connector-java:8.0.29")
    implementation("org.mongodb:mongo-java-driver:3.12.11")
    implementation ("org.hibernate.ogm:hibernate-ogm-mongodb:5.4.1.Final")
    implementation("jakarta.transaction:jakarta.transaction-api:2.0.1")
//  implementation("javax.transaction:jta:1.1")
//  implementation("org.hibernate:hibernate-entitymanager:6.0.0.Alpha7")


}

错误日志

2022-07-22 18:29:58.431 [eventLoopGroupProxy-4-1] TRACE o.h.j.b.i.PersistenceXmlParser - Persistence unit name from persistence.xml : Mdb
2022-07-22 18:29:58.431 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Located and parsed 2 persistence units; checking each
2022-07-22 18:29:58.431 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Checking persistence-unit [name=pu, explicit-provider=org.hibernate.jpa.HibernatePersistenceProvider] against incoming persistence unit name [Mdb]
2022-07-22 18:29:58.431 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Excluding from consideration due to name mis-match
2022-07-22 18:29:58.431 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Checking persistence-unit [name=Mdb, explicit-provider=org.hibernate.ogm.jpa.HibernateOgmPersistence] against incoming persistence unit name [Mdb]
2022-07-22 18:29:58.432 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.boot.spi.ProviderChecker - Persistence-unit [Mdb] requested PersistenceProvider [org.hibernate.ogm.jpa.HibernateOgmPersistence]
2022-07-22 18:29:58.432 [eventLoopGroupProxy-4-1] TRACE o.h.jpa.boot.spi.ProviderChecker - Checking requested PersistenceProvider name [org.hibernate.ogm.jpa.HibernateOgmPersistence] against Hibernate provider names
2022-07-22 18:29:58.432 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Excluding from consideration due to provider mis-match
2022-07-22 18:29:58.433 [eventLoopGroupProxy-4-1] DEBUG o.h.jpa.HibernatePersistenceProvider - Found no matching persistence units
2022-07-22 18:29:58.434 [eventLoopGroupProxy-4-1] TRACE o.h.jpa.HibernatePersistenceProvider - Could not obtain matching EntityManagerFactoryBuilder, returning null
2022-07-22 18:29:58.550 [eventLoopGroupProxy-4-1] ERROR ktor.application - Unhandled: GET - /jpa
jakarta.persistence.PersistenceException: No Persistence provider for EntityManager named Mdb

问题分析与解决方案

核心问题

  1. 依赖版本严重不兼容
    Hibernate Core 6.1.0.Final是Jakarta EE 9+版本,而Hibernate OGM MongoDB 5.4.1.Final仅兼容Hibernate Core 5.x(Java EE 8及以下),版本跨度导致OGM的持久化提供者无法被Hibernate Core 6.x识别加载。

  2. 命名空间与API前缀冲突
    persistence.xml使用了旧的Java EE命名空间,但依赖中混合了Jakarta EE的事务API,导致配置解析时出现不匹配,同时Hibernate 5.x需要使用javax.persistence前缀而非jakarta.persistence。

  3. 实体类重复配置风险
    同一个Student实体同时注册到两个不同类型的持久化单元(关系型+文档型),会引发实体映射逻辑冲突,后续可能出现更多未知问题。

修正步骤

1. 统一依赖版本,移除冲突依赖

修改build.gradle.kts,使用与Hibernate OGM 5.4.x兼容的Hibernate Core 5.x版本,同时调整Mongo驱动和事务API:

val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project

dependencies {
    implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-locations-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version")
    implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version")
    implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
    implementation("ch.qos.logback:logback-classic:$logback_version")
    testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
    
    // 移除无用的Maven插件依赖
    implementation("org.jetbrains.kotlin:kotlin-maven-noarg:1.2.30")
    
    // 使用与OGM兼容的Hibernate版本
    implementation("org.hibernate:hibernate-core:5.6.14.Final")
    implementation("org.hibernate:hibernate-entitymanager:5.6.14.Final")
    
    implementation("org.jetbrains.exposed:exposed-dao:0.38.2")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.38.2")
    implementation("org.ktorm:ktorm-core:3.5.0")
    
    implementation("mysql:mysql-connector-java:8.0.29")
    // 替换为OGM兼容的Mongo同步驱动
    implementation("org.mongodb:mongodb-driver-sync:4.6.1")
    implementation("org.hibernate.ogm:hibernate-ogm-mongodb:5.4.1.Final")
    
    // 使用Java EE的JTA API,适配Hibernate 5.x
    implementation("javax.transaction:jta:1.1")
    // 移除Jakarta版本API,避免冲突
    // implementation("jakarta.transaction:jakarta.transaction-api:2.0.1")
}

2. 修正persistence.xml配置

更新命名空间为JPA 2.1,统一使用javax.persistence前缀,并为MongoDB单独指定实体类:

<?xml version="1.0" encoding="UTF-8"?>
<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_1.xsd"
             version="2.1">

    <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.example.data.Student</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Students"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="mynewpassword"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>

    <persistence-unit name="Mdb" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
        <class>com.example.data.MongoStudent</class>
        <properties>
            <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
            <property name="hibernate.ogm.datastore.host" value="localhost:27017"/>
            <property name="hibernate.ogm.datastore.database" value="databasename"/>
            <property name="hibernate.ogm.datastore.create_database" value="true"/>
        </properties>
    </persistence-unit>

</persistence>

3. 创建MongoDB专属实体类

避免实体类跨数据源冲突,创建MongoStudent类,使用javax.persistence注解:

package com.example.data

import javax.persistence.Entity
import javax.persistence.Id

@Entity
class MongoStudent(
    @Id
    val id: Int,
    val name: String,
    val tech: String
)

4. 更新路由中的实体引用

修改Routing.kt,使用新创建的MongoStudent实体:

fun Application.configureRouting() {
    install(ContentNegotiation) {
        json()
    }

    routing {
        get("/") {
            call.respondText("Hello World!")
        }

        get("/jpa") {
            val a = MongoStudent(3, "George", "Python")

            val emf: EntityManagerFactory = Persistence.createEntityManagerFactory("Mdb")
            val em: EntityManager = emf.createEntityManager()

            em.transaction.begin()
            em.persist(a)
            em.transaction.commit()
            println(a)

            call.respond(HttpStatusCode.OK, "Working")
        }
    }
}

内容的提问来源于stack exchange,提问作者Anandakrishnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:01:35