我正在编写一个 GWT 应用程序,在服务器端使用 Hibernate。现在,我完全不知道用最少的代码将我的对象传输到 GWT 应用程序客户端的正确方法。我正在使用 Gilead 以避免将我的域模型中的类数量增加一倍 [1]。
首先,我的问题是我应该如何打开会话和交易。最初,我在每个 RPC 服务器调用上都这样做:
// begin rpc call
getCurrentSession
beginTransaction
// ...do stuff
commit
// session is automatically closed
// end rpc call
由于这会为每个 RPC 调用打开和关闭一个 Session,这是否也会每次都创建一个到数据库服务器的新连接?
无论如何,一旦我开始使用延迟加载的集合,我就会使用这种模式得到以下异常:
org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)`
在我看来,在 Gilead 有机会序列化集合对象之前会话已关闭,这会导致异常。
所以我试图通过自己显式打开 Session 来解决这个问题,这样可以防止它在每次交易后自动关闭,如下所示:
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