Grails和HibernateException:连接代理在事务完成后不可用

Mor*_*itz 5 grails hibernate grails-orm

我刚遇到一个我不明白的问题.我们的grails(2.2.2)应用程序在第一个用户登录后抛出以下异常.一旦完成,没有人再见过它.目前我们正在通过Geb测试再现它.

Caused by HibernateSystemException: connnection proxy not usable after transaction completion; nested exception is org.hibernate.HibernateException: connnection proxy not usable after transaction completion
->>   24 | doCall    in gibbons5.recommender.ActivityRatingTagLib$_closure1
Run Code Online (Sandbox Code Playgroud)

ActivityRatingTagLib中的行(由gsp调用)非常简单:

if (!User.get(session.user.id).permissions.publishStream) {
Run Code Online (Sandbox Code Playgroud)

如果我删除User.get()这里并立即访问session.user,一切正常,但它会在下一个TagLib调用中崩溃,在该调用中访问用户User.get().

我现在正在互联网上寻找解决方案,但是还没有任何有用的东西.由于这个例外似乎相当罕见,我想我们做的事情基本上是错的,但是什么呢?

User.groovy:

class User implements HttpSessionBindingListener {
    ...

    boolean isOnline = false
    Permissions permissions = new Permissions()

    static embedded = ['infoPopups', 'permissions', 'userSettings']

    void valueBound(HttpSessionBindingEvent event) {
        isOnline = true
    }

    void valueUnbound(HttpSessionBindingEvent event) {
        // we do not have a session any more
        withTransaction {
            def user = get(this.id)
            user.isOnline = false
            user.save()
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

Permissions.groovy:

class Permissions {
    boolean publishStream = false
}
Run Code Online (Sandbox Code Playgroud)

小智 0

OpenSessionInView 负责在使用 GSP 和 TagLib 时使休眠会话可用,但在布局中不可用。

当我遇到这个问题时,我的解决方案是用闭包包装数据库调用withTransaction

def myTag = { attrs, body ->
  User.withTransaction {
    //GORM methods...
  }
}
Run Code Online (Sandbox Code Playgroud)