首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JPA 不同實現 (Hibernate / EclipseLink) 與環境 (Java SE / EE) 的 persistence.xml 配置全解析

     編輯:Java 相關知識

前言

persistence.xml 是 JPA 標準配置描述符,但不同 Provider (Hibernate、EclipseLink/TopLink)、不同運行環境 (Java SE、Java EE / Jakarta EE) 的配置差異極大。本文系統對比兩大主流 Provider 在 SE/EE 環境下的完整配置模板,並解析核心屬性差異與遷移陷阱。

一、 核心結構對比

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/persistence
                                 https://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
  <persistence-unit name="PU_Name" transaction-type="RESOURCE_LOCAL | JTA">
    <provider>FQCN of Provider</provider>
    <jta-data-source>JNDI Name</jta-data-source>          
    <non-jta-data-source>JNDI Name</non-jta-data-source>    
    <class>com.example.Entity</class>                       
    <exclude-unlisted-classes>true/false</exclude-unlisted-classes>
    <properties>
      ... Provider 專屬屬性 ...
    </properties>
  </persistence-unit>
</persistence>

二、 Java SE 環境配置模板

1. Hibernate 5.x / 6.x (Jakarta Persistence 3.x)

<persistence-unit name="HibernateSE" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
  <class>com.example.User</class>
  <class>com.example.Order</class>
  <exclude-unlisted-classes>true</exclude-unlisted-classes>
  <properties>
    <!-- JDBC 連接 -->
    <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/>
    <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/mydb"/>
    <property name="jakarta.persistence.jdbc.user" value="dbuser"/>
    <property name="jakarta.persistence.jdbc.password" value="dbpass"/>
    <!-- Hibernate 專屬 -->
    <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
    <property name="hibernate.hbm2ddl.auto" value="update"/>  
    <property name="hibernate.show_sql" value="true"/>
    <property name="hibernate.format_sql" value="true"/>
    <property name="hibernate.connection.pool_size" value="10"/>  
    <property name="hibernate.current_session_context_class" value="thread"/>
  </properties>
</persistence-unit>

2. EclipseLink 3.x (原 TopLink Essentials)

<persistence-unit name="EclipseLinkSE" transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <class>com.example.User</class>
  <exclude-unlisted-classes>true</exclude-unlisted-classes>
  <properties>
    <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/>
    <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/mydb"/>
    <property name="jakarta.persistence.jdbc.user" value="dbuser"/>
    <property name="jakarta.persistence.jdbc.password" value="dbpass"/>
    <!-- EclipseLink 專屬 -->
    <property name="eclipselink.ddl-generation" value="create-tables"/>
    <property name="eclipselink.ddl-generation.output-mode" value="database"/>
    <property name="eclipselink.logging.level" value="FINE"/>
    <property name="eclipselink.target-database" value="PostgreSQL"/>
  </properties>
</persistence-unit>

三、 Java EE / Jakarta EE 環境配置模板 (容器管理 EntityManager)

1. Hibernate (WildFly / JBoss EAP / OpenLiberty 等)

<persistence-unit name="HibernateEE" transaction-type="JTA">
  <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
  <jta-data-source>java:/jdbc/MyDS</jta-data-source>
  <!-- EE 環境下容器掃描實體類,通常無需  -->
  <properties>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.show_sql" value="true"/>
    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>  
  </properties>
</persistence-unit>

2. EclipseLink (GlassFish / Payara / WebLogic)

<persistence-unit name="EclipseLinkEE" transaction-type="JTA">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <jta-data-source>jdbc/MyDS</jta-data-source>
  <properties>
    <property name="eclipselink.ddl-generation" value="create-tables"/>
    <property name="eclipselink.logging.level" value="FINE"/>
    <property name="eclipselink.target-server" value="SunAS9"/>  
  </properties>
</persistence-unit>

四、 關鍵差異對照表

維度Java SEJava EE / Jakarta EE
transaction-typeRESOURCE_LOCAL (應用手動管理 tx)JTA (容器管理 tx,EJB/CDI 注入 EntityManager)
DataSource 來源properties 中 JDBC URL/驅動/用戶/密碼<jta-data-source> JNDI 名稱,容器配置連接池
實體類發現需 <class> 顯式列出或 exclude-unlisted-classes=false 掃描容器自動掃描持久化單元內實體類 (可被 exclude-unlisted-classes 控制)
EntityManager 獲取Persistence.createEntityManagerFactory("PU").createEntityManager()@PersistenceContext EntityManager em 注入
事務控制em.getTransaction().begin/commit/rollback()容器自動管理 (EJB 方法邊界) 或 UserTransaction 手動
Provider 適配屬性無需容器適配必須 設置 hibernate.transaction.jta.platform / eclipselink.target-server 對應具體容器

五、 同一 persistence.xml 多持久化單元切換 (SE 環境)

<persistence ...>
  <persistence-unit name="HibernatePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.example.User</class>
    <properties> ... Hibernate 屬性 ... </properties>
  </persistence-unit>

  <persistence-unit name="EclipseLinkPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>com.example.User</class>
    <properties> ... EclipseLink 屬性 ... </properties>
  </persistence-unit>
</persistence>

運行時指定:Persistence.createEntityManagerFactory("HibernatePU") 或 "EclipseLinkPU"。注意: 同一持久化單元名稱下不能混合 Provider 屬性,否則啟動報錯。

六、 常見遷移陷阱與解決

  • 屬性前綴變更 (Jakarta EE 9+): javax.persistence.* → jakarta.persistence.*,Hibernate 專屬 hibernate.*、EclipseLink eclipselink.* 不變
  • SE 環境 exclude-unlisted-classes=true 導致實體遺漏: 必須逐個 <class> 列出,或設為 false 開啟掃描 (需確保類路徑可掃描)
  • EE 環境缺少 JTA 平台適配: 拋出 No JTA platform available,必須按容器設置對應屬性
  • DDL 自動生成衝突: 多持久化單元指向同一 Schema 且 hbm2ddl.auto=create-drop 導致啟動互刪表,生產環境統一用 validate 或 Flyway/Liquibase 管理遷移
  • ClassLoader 隔離導致 Provider 找不到: EAR/WAR 類加載器層級問題,確保 Provider JAR 在正確模塊 (通常放入 EAR/lib 或容器模塊)

七、 現代化建議:Spring Boot / Quarkus / Micronaut 零配置

Spring Boot 3.x: spring.datasource.* + spring.jpa.properties.hibernate.* 自動組裝 LocalContainerEntityManagerFactoryBean,無需 persistence.xml。
Quarkus / Micronaut: 編譯期處理註解,生成元數據,啟動極快,同樣無需 XML。
新專案首選零 XML 配置框架,僅在存量系統維護、多 Provider 熱切換、非 Spring 容器 EE 部署時手寫 persistence.xml。

結語

JPA 配置的核心複雜度在於 Provider 專屬屬性 × 運行環境 (SE/EE) × 容器適配 的排列組合。建立標準模板庫、CI 中包含多 Provider/多環境測試、遷移時逐屬性對照驗證,是驾驭這份複雜度的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved