懒得初始化角色集合:website.User.purchasedProducts,无法初始化代理 - 没有会话

时间:2016-08-28 15:26:49

标签: grails gorm

我正在尝试设置标记库以检查用户是否购买了产品。但是,当我的taglib运行时,我收到此错误:

ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[grailsDispatcherServlet] - Servlet.service() for servlet [grailsDispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/derbypro/index.gsp:124] Error executing tag <g:ifPurchased>: failed to lazily initialize a collection of role: website.User.purchasedProducts, could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: website.User.purchasedProducts, could not initialize proxy - no Session

这是我的标签lib:

package website

class PurchasedProductTagLib {
    def ifPurchased = { attrs, body ->
        if (!session.user) return

        if (Product.findById(attrs.product) in session.user.purchasedProducts) { // <-- error here
            out << body()
        }
    }

    def ifNotPurchased = { attrs, body ->
        if (!(Product.findById(attrs.product) in session.user?.purchasedProducts)) {
            out << body()
        }
    }
}

这是我的用户域类:

package website

import org.mindrot.jbcrypt.BCrypt

class User {
    String username
    String passwordHash
    String email

    static hasMany = [purchasedProducts: Product]

    User(String username, String password, String email) {
        this.username = username;
        passwordHash = BCrypt.hashpw(password, BCrypt.gensalt())
        this.email = email
    }
}

这似乎只是在登录后发生,如果用户注册(并重定向回到此页面),则不会发生此错误。

我的标签库嵌套在另一个内部,如果有的话。

1 个答案:

答案 0 :(得分:4)

嘛!日志说No session。您正在使用处于分离状态的对象。因此,要么将对象附加回来,要么只通过id获取对象。

if(!session.user.isAttached()){
     session.user.attach();
}

或者

Long id = session.user.id.toLong();
User user = User.get(id);

将对象附加到会话的方式。

修改

另一种解决方案可能是急切加载hasMany部分。但我不喜欢这个解决方案,因为它会减慢我的域名获取速度。此外,它还会获取所有地方可能不需要的hasMany数据。