我正在编写一个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
关于您遇到的最后一个问题:“具有相同标识符的不同对象已经在会话缓存中”,您应该使用合并,因为当您使用saveOrUpdate时,它假定没有对象具有相同的会话缓存中的标识符以及数据库中可能存在这样的标识符(因此orUpdate)在需要使用合并的会话中仍然有客户端对象。另见:http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/ – Ittai 2010-08-24 05:44:30