代码之家  ›  专栏  ›  技术社区  ›  rix0rrr

Hibernate、GWT和Gilead:会话、事务和缓存

  •  0
  • rix0rrr  · 技术社区  · 15 年前

    我正在编写一个GWT应用程序,在服务器端使用Hibernate。现在,我完全困惑于如何以最少的代码量将对象传输到GWT应用程序的客户端。我使用Gilead是为了避免在我的域模型[1]中类的数量翻倍。

    首先,我的问题是我应该如何开始会议和交易。最初,我在每个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有机会序列化collection对象之前,会话已经关闭,这会导致异常。

    因此,我试图通过自己显式地打开会话来解决这个问题,这样可以防止在每次事务之后自动关闭会话,如下所示:

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

    但是,当我这样做时,我看到了与会话对象缓存相关的各种奇怪行为。首先,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()
    

    我得到一个错误,比如“会话缓存中已经有一个具有相同标识符的不同对象”。

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

    2 回复  |  直到 15 年前
        1
  •  0
  •   Community CDub    8 年前

    Take a look a this answer 以及下面的评论。

    这里的问题和你的不一样——这是你的一个概括——即如何将JPA(Hibernate)与远程处理(即序列化对象并将它们发送到网络上阅读)结合起来。这不是一个简单而琐碎的问题,尽管这是一个常见的问题。看看我的建议,如果你不明白的话,在这里发表评论。

        2
  •  0
  •   Brian Deterling    15 年前

    我不使用Gilead,所以这可能是问题的一部分,但我使用ThreadLocal会话。在每个rpc调用中,我将逻辑包装在一个方法中,该方法总是在最终返回之前关闭ThreadLocal会话。第一次请求该线程时,将为其打开会话。

    但是,在关闭会话之前,必须完全初始化所有代理。最有可能的情况是,GWT试图在会话关闭后序列化您的POJO,当它到达代理或惰性集合时,它会无意中尝试初始化它。就我个人而言,我要么将pojo复制到单独的对象上,要么确保我确切知道哪些字段将被序列化,并提前“触摸”它们(例如,通过调用集合上的size())。但是如果你有一个嵌套很深的对象,那就很困难了。

    如果有一个GWT钩子可以让您在序列化之后、rpc线程完成之前执行代码,那就太好了。有可能,我只是不知道。