【问题标题】:Grails hibernate sessions opening/closing and lazy-initializationGrails休眠会话打开/关闭和延迟初始化
【发布时间】:2018-05-03 16:58:38
【问题描述】:

我有一堆与会话相关的异常,例如:

org.hibernate.LazyInitializationException failed to lazily initialize a collection of role: <...>, no session or session was closed
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
org.hibernate.TransientObjectException: cannot lock an unsaved transient instance: <...>
org.hibernate.UnresolvableObjectException: No row with the given identifier exists

我试图理解为什么。 所以我激活了 SQL 日志,当我查看休眠统计信息时,即使 http 请求没有结束,我也可以看到 80 个会话打开和 80 个关闭...... 我认为 OSIV(在 grails 中默认激活)可以防止一些惰性初始化异常的东西,但是据我所见,会话是打开然后按需关闭(对于事务)。

那么为什么在 http 请求结束之前至少有一个会话保持打开状态?

你有什么想法去了解/调查正在发生的事情吗?

非常感谢

Versions used:
    Grails 2.5.6
    GORM 3.1.4 
    Spring 4.1.9
    Hibernate3 3.6.10

【问题讨论】:

    标签: hibernate grails grails-orm lazy-loading grails-2.0


    【解决方案1】:

    您似乎正在尝试访问 grails 控制器/服务之外的实体上的 getter。

    如果你有延迟发起的关系,并且你想访问它,那么你应该使用withTransaction闭包:

    YourEntityClass.withTransaction{
        yourEntityClass.getX()
        // more logic
    }
    

    其他解决方法是:

    • 保持你的逻辑在Service
    • 使用急切加载

    【讨论】:

    • 那么你的意思是我应该从 grails-app 下的控制器和服务文件夹下的源访问我的实体?我的一些实体在与其他两个文件夹相同级别的文件夹下的源中引用(但称为 vms...)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    相关资源
    最近更新 更多