未能延迟初始化角色集合:website.User.purchasedProducts,无法初始化代理 - 无会话
failed to lazily initialize a collection of role: website.User.purchasedProducts, could not initialize proxy - no Session
我正在尝试设置标签库来检查用户是否购买了产品。但是,当我的 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
这是我的标签库:
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()
}
}
}
这是我的用户域 class:
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
}
}
这似乎只在登录后发生,如果用户改为注册(并被重定向回此页面),则不会发生此错误。
我的标签库相互嵌套,如果这样做的话。
嗯!正如日志所说 No session
。您正在使用处于分离状态的对象。因此,要么将对象附加回去,要么只通过 id 获取对象。
if(!session.user.isAttached()){
session.user.attach();
}
或
Long id = session.user.id.toLong();
User user = User.get(id);
将对象附加到会话的两种方式。
编辑
另一种解决方案可能是预先加载 hasMany 部分。但我不喜欢这种解决方案,因为它会减慢我的域名获取速度。此外,它会获取并非所有地方都需要的 hasMany 数据。
我正在尝试设置标签库来检查用户是否购买了产品。但是,当我的 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
这是我的标签库:
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()
}
}
}
这是我的用户域 class:
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
}
}
这似乎只在登录后发生,如果用户改为注册(并被重定向回此页面),则不会发生此错误。
我的标签库相互嵌套,如果这样做的话。
嗯!正如日志所说 No session
。您正在使用处于分离状态的对象。因此,要么将对象附加回去,要么只通过 id 获取对象。
if(!session.user.isAttached()){
session.user.attach();
}
或
Long id = session.user.id.toLong();
User user = User.get(id);
将对象附加到会话的两种方式。
编辑
另一种解决方案可能是预先加载 hasMany 部分。但我不喜欢这种解决方案,因为它会减慢我的域名获取速度。此外,它会获取并非所有地方都需要的 hasMany 数据。