引言
使用持久化架構能夠使數據庫事務處理變得更加容易。Java 持久化架構(Java Persistence Architecture)是一個非常不錯持久化選擇,通過使用 JPA,您可以不再需要使用復雜的 SQL 查詢,不必擔心性能問題,以及其它一些潛在的編程錯誤等。有很多的 JPA Persistence Provider 可供應用程序開發者來選擇,如 WebSphere JPA,OpenJPA 和 Hibernate 等等。WebSphere Application Server 支持配置使用大多數的 JPA Persistence Provider。本文將以 WebSphere JPA,OpenJPA 和 Hibernate 為例,來介紹如何在 WebSphere Application Server 中使用不同的 JPA Persistence Provider。
引言
使用持久化架構能夠使數據庫事務處理變得更加容易。Java 持久化架構(Java Persistence Architecture)是一個非常不錯持久化選擇,通過使用 JPA,您可以不再需要使用復雜的 SQL 查詢,不必擔心性能問題,以及其它一些潛在的編程錯誤等。
IBM WebSphere Application Server V7 交付了 Java Persistence API(JPA)2.0 功能部件包。 IBM JPA2.0 實現基於 Apache OpenJPA,包含了重要的基於標准的新特性,提高了開發效率,同時也提供額外的 API 來增加應用的性能。
除了 WebSphere JPA 以外,現在還有很多其它的 JPA Persistence Provider 可供應用程序開發者來選擇,如 OpenJPA,Hibernat,EclipseLink 等等。WebSphere Application Server 支持配置使用大多數的 JPA Persistence Provider。本文將以 WebSphere JPA,OpenJPA 和 Hibernate 為例,來介紹如何在 WebSphere Application Server 中使用不同的 JPA Persistence Provider。
先決條件
本文假定讀者了解 JPA 的相關知識,並且了解 OpenJPA,Hibernate。有關有幫助的背景信息,請參閱參考資源。
導入示例應用
我們將使用安裝了 JPA 2.0 功能部件包的 WebSphere Application Server 7.0.0.9,以 Rational Application Developer ( 簡稱 RAD) 7.5 為開發環境。
為了簡單,我們將使用 RAD 7.5 的一個示例應用作為舉例的應用。首先需要將示例應用導入到 RAD 7.5 中。
啟動 RAD7.5,打開一個空的工作區,點擊 Help->Samples,在彈出的面板左側,找到 Samples->Application Samples->EJB->EJB 3.0 Counter Sample,點擊 Import Sample,示例應用就會導入到您的工作區中了。
圖 1. 啟動工作區
圖 2. RAD 7.5 幫助面板
現在示例應用已經導入到工作區來了,接下來,您需要在 RAD 中創建一個服務器的定義。我們假設您已經准備好一個本地單服器 WebSphere Application Server V7.0.0.9 的安裝,並且也安裝了 JPA2.0 功能部件包。我們還假設您已經創建了一個概要文件。(有關安裝和概要文更多信息,請參見參考資料。)
點擊 Windows->Show View->Server->Servers(如果 Server 沒有出現在選項列表中的話,點擊 Others,來獲得更多的選項)。
圖 3. 選擇 Server 視圖
在 servers 標簽,右鍵 New->Server
圖 4. 創建新的服務器
選擇 WebSphere Application Server 7.0 並指向 WebSphere Application Server 的安裝目錄。如果您啟用了 WebSphere Application Server 的安全性,請指定用戶名和密碼。現在您可以啟動或停止應用服務器,以及向其上添加應用。
圖 5. 創建新的運行服務器
右鍵點擊應用服務器,在彈出的菜單上選擇“ Add and Remvoe Projects … ”,在“ Configured Project:”面板上將 EJB Counter Sample 應用移到右側。當您點擊“ Finish ”之後,應用就布署到了應用服務器上。
圖 6. 添加應用到服務器上
如果您已經將設置好了您的工作空間,應用服務器,以及數據庫,那麼您就可以開始測試應用了。
配置使用不同的 Persistence Provider
您有兩種方式來在 WebSphere Application Server 中使用不同的 JPA Provider。一種方式是通過改變 WebSpehre Application Server 的默認 Persistence Provider,另外一種方式,就是通過在 persistence.xml 文件中定義來指定不同的 persistence provider。接下來,將分別舉例介紹這兩種方式。
通過更改 WebSphere Application Server 默認 Persistence Provider 來實現使用不同的 Persistence Provider
因為 RAD7.5 的示例應用是基於 JPA 1.0 的,所以我們需要修改 persistence.xml 和 orm.xml 文件,將其改為使用 JPA 2.0。在 EJB 3.0 Counter Sample 示例應用中,這兩個文件位於 EJBCounterSample->ejbModule->META-INF 目錄下。如下所示,將它們的版本從 1.0 改為 2.0。
清單 1. orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
</entity-mappings>
並在 persisten.xml 文件中增加如下的屬性
表 1. Hibernate 屬性
表 2. OpenJPA 屬性
清單 2. persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="Counter">
<jta-data-source>jdbc/EJB3SampleDatasource</jta-data-source>
<class>com.ibm.websphere.ejb3sample.counter.JPACounterEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- HIBERNATE properties -->
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
<property name="jta.UserTransaction" value="java:comp/UserTransaction"/>
<!-- OPENJPA properties -->
<property name="openjpa.Log" value="none"/>
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
</properties>
</persistence-unit>
</persistence>
接下來,您需要下載 Hibernate 指定的第三方 ja r 文件,並把它們加入到 WebSphere Application Server 的共享庫中。您可以從 Hiberante 的網站上下載這些 jar 文件。下面這些 jar 文件,是保證本示例應用正常工作所需要 jar 文件。
antlr-2.7.6.jar
commons-collections-3.1.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar
dom4j-1.6.1.jar
hibernate3.jar
javassist-3.9.0.GA.jar
jta-1.1.jar
slf4j-api-1.5.8.jar
您還需要下載 OpenJPA 指定的 jar 文件,可以從 apache 的網站上下載。下面這些 jar 文件,是保證本示例應用正常工作所需要 jar 文件。
commons-collections-3.2.1.jar
commons-lang-2.1.jar
commons-pool-1.5.3.jar
serp-1.13.1.jar
openjpa-2.0.0.jar
或者為了簡單,也可以使用 openjpa-all-2.0.0.jar。
您可以直接將這些 jar 文件放到應用服務器的 lib 目錄中去,但是為了有更好的可維護性,我建議創建一個共享庫(Shared Library)。這樣做,您可以使每一個應用服務器,節點,以及集群都可以使用這個共享庫,而不需要覆蓋掉其它正在被使用的 jar 文件。接下來,我們就來創建一個共享庫,打開 WebSphere Application Server 的管理控制台。在左側導航條上找到 環境 -> 共享庫。創建一個新的共享庫,名為 JPA-Shared Libraries。在類路徑文本框裡,把這些 jar 文件的所在完整路徑名都填入類路徑文本框中。如果是在分布式環境中,請使用 WebSphere 變量來定義。
圖 7. 創建 Hiberante 共享庫
對於 OpenJPA,您需要勾選上 為該共享庫使用單獨的類加載器。
圖 8. 創建 OpenJPA 共享庫
接下來,您需要將應用服務器與共享庫關聯起來。在 WebSphere Application Server 的管理控制台中,選擇 服務器 -> 服務器類型 ->WebSphere 應用服各器。打開應用服務器 Server1 屬性頁面,在頁面的右側,打開 Java 和進程管理,並選擇 類裝入器。創建一個新的類裝入器,並選擇類已裝入並且先使用應用程序類裝入器。
圖 9. 創建類裝入器
在創建的類裝入器的頁面右側,選擇共享庫引用。添加您在前一步創建的共享庫。這樣服務器就會在下一次啟動時加載這些 jar 文件了。
圖 10. 添加共享庫
對於 OpenJPA,您不能將應用服務器與該共享庫關聯起來,因為 WebSphere 默認的 JPA wsjpa 會將其覆蓋。您必須將您的應用與該共享庫關聯起來。到應用定義的頁面 應用程序 -> 應用程序類型 ->WebSphere 企業應用程序 ->EJBCounterEAR。在應用程序屬性頁面,選擇 引用 分類下的 共享庫引用,在共享庫引用頁面,選擇 EAR 中的每一個模塊(如果您不確定哪個一個模塊使用了 JPA),添加剛才創建的共享庫。
圖 11. 添加共享庫
現在應用服務器和應用程序都可以訪問 JPA Provider 了,您可以指定是否使用 WebSphere Application Server 默認的 wsjpa Provider。
可以通過管理控制台來更改默認 provider,在左側導航條上,點擊 服務器 -> 服務器類型 ->WebSphere 應用服務器,選擇 Server1,在應用服務器屬性頁面打開容器服務,選擇 默認 Java 持久化 API 設置。在該頁面上,顯示了 WebSphere 提供的兩個默認的 Persistence Provider:WebSphere 實現的 JPA 和 OpenJPA。您也可以通過選擇第二個單選按扭,來填入像 Hibernate 這樣的第三方 JPA Provider。
接下來,我們通過改變 WebSphere 默認的 Persistence Provider 並來逐一驗證 WebSphere JPA、OpenJPA 和 Hibernate 是否能夠正常裝載。
通過 http://localhost:port/EJBCounterWeb/counter,來訪問應用程序並驗證它是否正常工作。
使用 WebSphere JPA 作為默認的 JPA Persistence Provider
此時不要在服務器(server1)上以及應用程序上加載 OpenJPA 和 Hiberante 的共享庫。
在 <WAS_HOME>/profiles/<profile>/logs/<server>/SystemOut.log,您可以找到下面這段文字證明此時加載的是 WebSphere JPA :
JPAComponentI I CWWJP0026I: The Java Persistence API (JPA) component is initializing.
JPAComponentI I CWWJP0006I: The com.ibm.websphere.persistence.PersistenceProviderImpl class is loaded as the default Java Persistence API (JPA) provider.
JPAComponentI I CWWJP0027I: The Java Persistence API (JPA) component has initialized.
使用 OpenJPA 作為默認的 JPA Persistence Provider
此時需要在應用程序上加載 OpenJPA 的共享庫,並且改變應用服務器(server1)的默認 Persistence Provider 為 OpenJPA,重新啟動應用服務器。
在 <WAS_HOME>/profiles/<profile>/logs/<server>/SystemOut.log,您可以找到下面這段文字證明此時加載的是 OpenJPA:
JPAComponentI I CWWJP0026I: The Java Persistence API (JPA) component is initializing.
JPAComponentI I CWWJP0006I: The org.apache.openjpa.persistence.PersistenceProviderImpl class is loaded as the default Java Persistence API (JPA) provider.
JPAComponentI I CWWJP0027I: The Java Persistence API (JPA) component has initialized.
使用 Hiberante 作為默認的 JPA Persistence Provider
此時需要在應用服務器 (server1) 上加載 Hiberante 的共享庫,並且改變應用服務器 (server1) 的默認 Persistence Provider 為 Hibernate JPA (org.hibernate.ejb.HibernatePersistence),重新啟動應用服務器。
在 <WAS_HOME>/profiles/<profile>/logs/<server>/SystemOut.log,您可以找到下面這段文字證明此時加載的是 Hiberante JPA:
JPAComponentI I CWWJP0028I: The Java Persistence API (JPA) component is starting. JPAComponentI I CWWJP0006I: The org.hibernate.ejb.HibernatePersistence class is loaded as the default Java Persistence API (JPA) provider.
JPAComponentI I CWWJP0017I: The Java Persistence API (JPA) component has started.
通過在 persistence.xml 文件中定義來指定不同的 Persistence Provider
如果您希望通過編程的方式來改變您的 Persistence Provder,您可通過修改 persistence.xml 文件來實現,僅需要加上 <provider> 標簽即可。
修改 persistence.xml 文件,在我們的例子中,
清單 3. 通過編程試指來改變 Persistence Provider
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="Counter">
<provider>com.ibm.websphere.persistence.PersistenceProviderImpl
</provider>
Or
<provider>org.hibernate.ejb.HibernatePersistence</provider>
Or
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/EJB3SampleDatasource</jta-data-source>
<class>com.ibm.websphere.ejb3sample.counter.JPACounterEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- HIBERNATE properties -->
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
<property name="jta.UserTransaction" value="java:comp/UserTransaction"/>
<!-- OPENJPA properties -->
<property name="openjpa.Log" value="none"/>
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
</properties>
</persistence-unit>
</persistence>
驗證正在使用的 JPA Provder
如果您是更改了應用服務器的默認 JPA Provder,您需要重新啟動應用服務器,通過查看 SystemOut.log 來驗證您正在使用的 JPA Provider。
如果您是通過編程方式在改變應用程序使用的 JPA Provider,您不需要重新啟動應用服務器,而是需要在應用程序中增加如下的代碼來驗證加載的是哪個 Persistence Provider。
清單 4. 驗證加載 Persistence Provider 的代碼
清單 4. 驗證加載 Persistence Provider 的代碼
void showJPAProvider() {
System.out.println("////////////////////////////////);
System.out.println("JPA Provider Implementation: "
+ emf.getClass()); System.out.println("/////////////);
}
確保上面這個方法能夠在 SystemOut.log 中顯示 Entity Manger Factory 類,而且這個類是在任何 JPA 被調用的時候使用的類。上面的方法會打印出 JPA 實現方法,例如,org.apache,com.ibm,org.hibernate,等等。
清單 5. SystemOut.log 裡面的輸出結果
SystemOut O /////////////////////////////////////////
SystemOut O JPA Provider Implementation:
class com.ibm.ws.persistence.EntityManagerFactoryImpl
SystemOut O /////////////////////////////////////////
結束語
本文介紹了兩種更改 JPA Provider 的方式,一種通過更改 WebSphere Application Server 的默認 JPA Provder;另一種是通過編程的方式通過增加 <provider> 標簽來指定不同的 JPA Provider。您可以在實際應用中根據需要選技您合適的方適來使用。