2010-01-07 85 views
0

我正在編寫一個GWT應用程序,在服務器端使用Hibernate。現在,我對使用最少代碼將我的對象轉移到GWT應用程序的客戶端的正確方法感到困惑。我正在使用Gilead來避免在我的域模型[1]中增加兩倍的類。休眠,GWT和Gilead:會話,事務和緩存

首先,我的問題是我應該如何打開會話和交易。起初,我這樣做是對每一個RPC服務器調用:

// begin rpc call 
getCurrentSession 
beginTransaction 
// ...do stuff 
commit 
// session is automatically closed 
// end rpc call 

由於這打開和關閉會話,每RPC調用,這是否也創造了每一次的數據庫服務器的新連接?

無論如何,只要我開始使用延遲加載的集合,我使用這種模式出現以下情況例外:

org.hibernate.HibernateException: collection is not associated with any session 
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)` 

在我看來,本次會議是封閉Gilead公司得到一個機會來序列前集合對象,這會導致異常。

所以,我想通過明確會議開幕嘍,防止它被自動關閉每次交易後,像這樣來解決這個問題:

openSession 
// begin rpc call 
beginTransaction 
// ...do stuff 
commit 
// end rpc call 

// next rpc call 
beginTransaction 
// ...etc 

然而,當我這樣做,我看到與Session對象緩存相關的各種奇怪行爲。首先,createQuery()。executeUpdate()似乎不會使會話緩存失效,儘管我已經閱讀過它應該使用的各種網站。當我嘗試通過調用session.flush(),session.clear()等等的各種置換來嘗試解決該問題時,下一個錯誤是在Gilead或Beanlib內部深入序列化的「ClassCastException:null」 。

另一件事,當我想是這樣的:

clients get an object from the server 
client modifies object 
client sends object back 
server calls session.saveOrUpdate() 

我得到一個錯誤,如「具有相同標識符不同的對象是已經在會話高速緩存」。

什麼是正確的方法來設置這種事情?我應該如何確定會話的範圍,以及如何處理緩存?我無法想象我是唯一一個嘗試這個並且遇到問題的人,但是好的導遊似乎很難得到。

[1] http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html

+0

關於您遇到的最後一個問題:「具有相同標識符的不同對象已經在會話緩存中」,您應該使用合併,因爲當您使用saveOrUpdate時,它假定沒有對象具有相同的會話緩存中的標識符以及數據庫中可能存在這樣的標識符(因此orUpdate)在需要使用合併的會話中仍然有客戶端對象。另見:http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/ – Ittai 2010-08-24 05:44:30

回答

0

Take a look a this answer和下面的評論。

這裏的問題與你的問題不一樣 - 它是你的一個概括 - 即如何將JPA(Hibernate)與遠程處理(即序列化對象併發送它們以通過線路讀取)結合使用。這不是一個容易和微不足道的問題,雖然它是一個普遍的問題。在那裏檢查我的建議,如果你不瞭解某些內容,請在這裏發表評論。

0

我不使用Gilead,這可能是問題的一部分,但我使用ThreadLocal會話。在每個rpc調用中,我將該邏輯封裝在始終在最終返回之前關閉ThreadLocal會話的方法中。第一次請求時,會話將爲該線程打開。

但是,在關閉會話之前,您必須完全初始化任何代理。最有可能的是,在會話結束後,GWT試圖序列化POJO,當它到達代理或惰性集合時,它會無意中嘗試初始化它。就個人而言,我要麼將POJO複製到單獨的對象中,要麼確保我確切知道哪些字段將被序列化,並提前「觸摸」它們(例如,通過調用集合上的size()。這很難,如果你有一個深嵌套的對象。

如果有一個GWT鉤子,讓你在序列化之後但rpc線程完成之前執行代碼將是很好的。有可能有,我只是不知道關於它