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

將遺留 Hibernate 應用遷移至 OpenJPA 與 EJB 3.0(下):關系映射、鎖定與配置遷移

     編輯:Java 相關知識

遷移指南(下):關系映射、延遲加載、對象標識、鎖定策略與配置參數對照

一對多關系遷移

對象模型:父實體 Address 持有 Set<Phone> phones,子實體 Phone 可選擇持有反向引用。

Hibernate 單向映射:外鍵在子表,不映射到子對象屬性,外鍵列必須可空(先插入子行再更新)。

Hibernate 雙向映射:子對象有外鍵屬性,列可非空,但引入循環依賴與雙向維護成本。

OpenJPA 關鍵差異:不支援單向一對多外鍵映射,必須使用連接表。建議將單向轉為雙向(添加反向屬性),修改代碼雙向維護關系,避免變更數據庫結構。

<!-- OpenJPA 雙向一對多 XML 映射 -->
<entity class="Address">
    <one-to-many name="phones" mapped-by="address">
        <cascade><cascade-all/></cascade>
    </one-to-many>
</entity>
<entity class="Phone">
    <many-to-one name="address">
        <join-column name="ADDR_TID"/>
    </many-to-one>
</entity>

特殊功能遷移:

  • inverse="true" → OpenJPA 非擁有端(無外鍵端)
  • cascade="all-delete-orphan" → JPA 無標準對應,OpenJPA 提供專有 @ElementDependent;標準遷移需代碼顯式 remove() 子對象
  • 級聯操作需雙向定義 cascade=CascadeType.ALL,否則 merge() 會失敗(OpenJPA 0.9.7 已知問題)

多對多關系遷移

映射表由擁有端持有。Hibernate 使用 inverse="true" 標識非擁有端;OpenJPA 使用 mapped-by 引用擁有端屬性名。

<!-- OpenJPA 多對多 XML 映射 -->
<entity class="User"> <!-- 擁有端 -->
    <many-to-many name="groups">
        <join-table name="T_USER_GROUP">
            <join-column name="USER_TID"/>
            <inverse-join-column name="GROUP_TID"/>
        </join-table>
    </many-to-many>
</entity>
<entity class="Group"> <!-- 非擁有端 -->
    <many-to-many name="users" mapped-by="groups"/>
</entity>

延遲初始化策略遷移

兩者默認均為 LAZY。禁用延遲(啟用 EAGER):

  • Hibernate:集合 lazy="false",類 lazy="false"
  • OpenJPA:集合 fetch="EAGER"

分離對象訪問差異:Hibernate 拋出異常,OpenJPA 返回空集合。JPA 規範未規定行為,不可依賴。建議方案:

  1. Session Facade 中按需顯式初始化集合
  2. 延長 EntityManager 生命週期至視圖渲染完成(Open Session in View)
  3. 使用擴展持久化上下文

對象標識(OID)遷移

最佳實踐:系統生成整數鍵(人工鍵),映射為 Long。Hibernate 使用 sequence 生成器;OpenJPA 使用 @SequenceGenerator + @GeneratedValue(strategy=SEQUENCE)。外鍵均基於 OID,帶 ON DELETE RESTRICT 約束。

樂觀鎖與悲觀鎖遷移

版本欄位映射基本一致:Hibernate <version>,OpenJPA <version> + @Version。

JPA 僅標準化樂觀鎖。遷移使用悲觀鎖的應用,需在 persistence.xml 配置 OpenJPA 擴展屬性:

<property name="openjpa.LockManager" value="pessimistic"/>
<property name="openjpa.ReadLockLevel" value="read"/>
<property name="openjpa.WriteLockLevel" value="write"/>
<property name="openjpa.jdbc.TransactionIsolation" value="repeatable-read"/>

或編程方式通過 FetchPlan.setReadLockMode(LockModeType.WRITE) 控制單事務鎖定級別。

配置參數對照表

類別HibernateOpenJPA
數據庫方言hibernate.dialectopenjpa.jdbc.DBDictionary (可選)
驅動類connection.driver_classopenjpa.ConnectionDriverName
連接 URLconnection.urlopenjpa.ConnectionURL
用戶名connection.usernameopenjpa.ConnectionUserName
密碼connection.passwordopenjpa.ConnectionPassword
映射文件<mapping resource="..."/><mapping-file>META-INF/orm.xml</mapping-file>
顯示 SQLshow_sql=trueopenjpa.Log=SQL=TRACE + ConnectionFactoryProperties=PrettyPrint=true

建議:先遷移核心配置,再通過負載測試引入優化參數。

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