2010-01-07 81 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线程完成之前执行代码将是很好的。有可能有,我只是不知道关于它