Tuesday, December 9, 2008

Run appfuse 2.0.2 with JPA

最近發現一件事,似乎越來越多的軟體公司,若是用 J2EE + MVC 架構,以 JPA 取代 Hibernate 的情況越來越多。說實在的,看了一下 JPA 的 spec,跟以往 EJB 一樣,他是一個空殼子,真正的 implementation 可以是任何 framework。

目前看到的 JPA implementation 有 Hibernate 、TopLink 及 OpenJPA,在 appfuse 2.0.2 中用的是 Hibernate 最新版 3.3.0 GA 版,但在試 appfuse 2.0.2 with JPA 中發現一些問題,讓我摸索好久才試出來,提供那些卡住的人一些解法。試之前請先參考
Appfuse 2.0.2 安裝步驟(steps for appfuse 2.0.2 installation) 中的
1. 安裝 maven-2.0.9 及設定環境變數


1. 建立 appfuse 2.0.2 的 archetype 到 d:\projects 中
d:\projects> mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-struts -DremoteRepositories=http://static.appfuse.org/releases -DarchetypeVersion=2.0.2 -DgroupId=com.mycompany.app -DartifactId=myprojectjpa

PS : 有別於之前的範例,這裡用 struts 2.0 作為 MVC 的 framework,artifactId 也改為 myprojectjpa,避免與之前的範例衝到

2. 安裝 mysql (若尚未安裝)
mysql 的網站下載 mysql for Windows 並安裝 (此時裝的是 v5.0.x )。root 的密碼暫定為 root

3. 修改 root 的密碼及更改 dao framework 為 jpa

3.1 因 預設在 myproject 中的 pom.xml 的 mysql 密碼為 "空白",所以必須將此部份的空白填入真正的 root 密碼,在做 install 時才能將 table 及 測試資料放到 mysql 的資料庫中。編輯 pom.xml 並在 line 975 修改
<jdbc.password>
</jdbc.password> 為
<jdbc.password>root</jdbc.password> (假設 mysql root 的密碼為 root)

3.2 修改 line 938 將 hibernate 改成 jpa

3.3 修改 line 142 將 annotationconfiguration 改成 jpaconfiguration

3.4 這時候別急著跑 mvn jetty:run-war ,因為你一跑,會出現
javax.persistence.PersistenceException: No name provided and several persistence
units found
我因為這個 error 卡了 2,3 個小時,後來 google 後才知道要

3.4.1 remove D:\projects\myprojectjpa\src\main\resources\hibernate.cfg.xml
3.4.2 remove D:\projects\myprojectjpa\src\test\resources\hibernate.cfg.xml
3.4.3 remove D:\projects\myprojectjpa\src\main\resources\META-INF\persistence.xml

4. 取得 appfuse 的 source code 以便日後 debug 用
d:\projects> cd myproject
d:\projects\myproject> mvn appfuse:full-source

5. 利用 command line 啟動 appfuse
d:\projects\myproject> mvn clean jetty:run-war
執行 clean 的目的是要把 war 中的 hibernate.cfg.xml 清除掉,不然會造成 error

org.hibernate.DuplicateMappingException: Duplicate collection role mapping com.m
ycompany.app.model.User.roles

一旦執行此 mvn jetty:run-war,appfuse 就會直接啟動在 port 8080。此時可以用 firefox 檢測 appfuse 是否啟動成功。將 url 指向 http://localhost:8080 可以得到此畫面

No comments: