ZK是個好學易用的component-based, event-driven AJAX framework,可以只用Java語法開發,而擁有AJAX的技術達成的更新部份網頁效果。
Hibernate用在web-based application時,在view layer會有眾所周知的lazy loading problem,如果使用JSP等會發出HTTP request的前端技術,可以透過OpenSessionInViewFilter來解決這個問題。
不過,如果使用AJAX技術時,網頁畫面的更新通常不會發出HTTP request,因此上述解法將無法用在ZK這樣的AJAX framework中。
典型的master-detail情況是,在ZK的元件中,點選listbox中一筆紀錄(master),要顯示該筆資料的詳細資料欄位(detail),例如點了一筆員工姓名,要顯示員工詳細資料。但是這些詳細資料中,有些欄位或集合是在hibernate中設定為lazy initialization的,也就是在抓出listbox中的簡要資料時,沒有被hibernate載入的。
這時hibernate會透過model物件中附帶的Session物件去做再次查詢,如果該Session已經關閉則會拋出lazy initialization exception。
有一種作法稱為Long Session,也就是開啟一個session直到應用程式結束才關閉。
我的解法比較適用在DAO層採用 繼承Spring的 HibernateDAOSupport的架構,他的特性是CRUD的method多半用 HibernateTemplate來實做各類查詢。這樣的架構Session會在HibernateTemplate 中開啟、關閉,也就是查詢結束後Session就關閉了。如果採用這樣的架構,Long Session的解法跟此架構格格不入,ZK所提供的OpenSessionInViewListener也跟這樣的架構無法共同運作,因為DAO層與OpenSessionInViewListener不是使用同一個Session。
所以我的解法是在頁面點選一筆資料的同時,先initialize該筆的lazy-loaded collection,樣本程式碼如下:
public void initializeProxy(Employee employee){
if (!Hibernate.isInitialized(employee.getFamilys())){
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
session.lock(employee, LockMode.NONE);
//initialize all proxies of a employee
Hibernate.initialize(employee.getFamilys());
//...
tx.commit();
session.close();
}
}
優點是可以維持使用HibernateDAOSupport的架構,只要增加一個mehtod去intialize proxy物件就好。
缺點是當model object (ex: Employee)有collection增減時,這的mothod就需要重寫。
Hibernate用在web-based application時,在view layer會有眾所周知的lazy loading problem,如果使用JSP等會發出HTTP request的前端技術,可以透過OpenSessionInViewFilter來解決這個問題。
不過,如果使用AJAX技術時,網頁畫面的更新通常不會發出HTTP request,因此上述解法將無法用在ZK這樣的AJAX framework中。
典型的master-detail情況是,在ZK的元件中,點選listbox中一筆紀錄(master),要顯示該筆資料的詳細資料欄位(detail),例如點了一筆員工姓名,要顯示員工詳細資料。但是這些詳細資料中,有些欄位或集合是在hibernate中設定為lazy initialization的,也就是在抓出listbox中的簡要資料時,沒有被hibernate載入的。
這時hibernate會透過model物件中附帶的Session物件去做再次查詢,如果該Session已經關閉則會拋出lazy initialization exception。
有一種作法稱為Long Session,也就是開啟一個session直到應用程式結束才關閉。
我的解法比較適用在DAO層採用 繼承Spring的 HibernateDAOSupport的架構,他的特性是CRUD的method多半用 HibernateTemplate來實做各類查詢。這樣的架構Session會在HibernateTemplate 中開啟、關閉,也就是查詢結束後Session就關閉了。如果採用這樣的架構,Long Session的解法跟此架構格格不入,ZK所提供的OpenSessionInViewListener也跟這樣的架構無法共同運作,因為DAO層與OpenSessionInViewListener不是使用同一個Session。
所以我的解法是在頁面點選一筆資料的同時,先initialize該筆的lazy-loaded collection,樣本程式碼如下:
public void initializeProxy(Employee employee){
if (!Hibernate.isInitialized(employee.getFamilys())){
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
session.lock(employee, LockMode.NONE);
//initialize all proxies of a employee
Hibernate.initialize(employee.getFamilys());
//...
tx.commit();
session.close();
}
}
優點是可以維持使用HibernateDAOSupport的架構,只要增加一個mehtod去intialize proxy物件就好。
缺點是當model object (ex: Employee)有collection增減時,這的mothod就需要重寫。
留言