Rebundle hibernate3.2
Nov
源起
想要加上 ORM 這一層,同時練習一下 javax.persistence 與 EntityManager 的用法。 所以下面會包成兩包,一包是 haha.hibernate,一包是 haha.helloem。
關於資料庫的部份請參考之前作法 Rebudle Derby
部分參考連結 :
An Introduction to Java Persistence for Client-Side Developers
haha.hibernate
包這個主要將相依的東西納入即可,同時匯入需要的 jdbc 等類別。
META-INF/MANIFEST.MF
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: haha.hibernate Bundle-SymbolicName: haha.hibernate Bundle-Version: 1.0.0 Bundle-Localization: plugin Bundle-ClassPath: ., lib/hibernate3.jar, lib/hibernate-annotations.jar, lib/ejb3-persistence.jar, lib/dom4j-1.6.1.jar, lib/commons-collections-2.1.1.jar, lib/cglib-2.1.3.jar, lib/asm.jar, lib/jta.jar, lib/ehcache-1.2.jar, lib/hibernate-entitymanager.jar, lib/javassist.jar, lib/jboss-archive-browsing.jar Import-Package: org.apache.commons.logging, org.apache.derby.jdbc, org.osgi.framework;version="1.4.0", org.osgi.service.component;version="1.0.0", org.osgi.service.log;version="1.3.0" Export-Package: haha.hibernate, javax.persistence, org.hibernate.proxy Service-Component: OSGI-INF/service.xml Eclipse-BuddyPolicy: registered
src/haha/hibernate/HibernateDservice.java
到底要包出啥服務實在不清楚,直接做看看。
package haha.hibernate;
import javax.persistence.EntityManagerFactory;
public interface HibernateDservice {
EntityManagerFactory getEntityManagerFactory(String name);
}
src/haha/hibernate/HibernateDserviceImpl.java
public EntityManagerFactory getEntityManagerFactory(String name) {
return Persistence.createEntityManagerFactory(name);
}
haha.helloem
這個包啟動時會找到 haha.hibernate 的服務,然後取出 EntityManager 來用,將一個物件放入冰箱保存。
META-INF/MANIFEST.MF
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: haha.helloem Bundle-SymbolicName: haha.helloem Bundle-Version: 1.0.0 Bundle-Localization: plugin Import-Package: haha.hibernate, javax.persistence, org.hibernate.proxy, org.osgi.framework;version="1.4.0", org.osgi.service.component;version="1.0.0", org.osgi.service.log;version="1.3.0" Service-Component: OSGI-INF/reference.xml Eclipse-RegisterBuddy: haha.hibernate
META-INF/persistence.xml
<persistence-unit name="sample" transaction-type="RESOURCE_LOCAL">
<class>haha.hibernate.demo.User</class>
<properties>
<property name="hibernate.connection.driver_class"
value="org.apache.derby.jdbc.ClientDriver"/>
<property name="hibernate.connection.url"
value="jdbc:derby://localhost:1527/derbyDemoDB;create=true"/>
<property name="hibernate.connection.username"
value="user1"/>
<property name="hibernate.connection.password"
value="xxxxx"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
</properties>
</persistence-unit>
User object
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "usertb")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private Integer age;
public User() {
}
// setXX and getXX ...
}
ejb3 container ?
既然包 hibernate 來當 ORM 來用,似乎用容器來支援一些操作比較方便,這些服務當然與可以自己來做,不過既有現成又測過,就來用看看。
Embeddable EJB 3.0
http://docs.jboss.org/ejb3/embedded/embedded.html
測的版本是jboss-EJB-3.0_Embeddable_ALPHA_9 ,並無法完成轉包到 OSGi 上跑,它的簡易啟動做法如下。
EJB3StandaloneBootstrap.boot(null); EJB3StandaloneBootstrap.scanClasspath();
問題是這個 scanClasspath 是直接找 classpath 的 jar 或是目錄,而這些東西在 OSGi 環境中卻不存在,要改應該也可以,只是這樣似乎違背用既有東西減少開發的原意。
觀察
- EntityManager 跟 Hibernate 的 session 一樣,並非 Thread-safe,還要用些做法來幫忙,否則出錯都不知道在哪裡。
- 用 ejb3 container 似乎是個好方法,不過測試 jboss embedded ejb3 的方式不是很順利,該容器載入的模式是針對 jar 等固定模式,對於 osgi 的動態方式,並無法提供夠用的 java.class.path 來掃描那些 ejb3 檔案。
- DAO 部份也需要考慮如何實做。