2016-08-28 15 views
2

ユーザーが製品を購入したかどうかを確認するタグlibを設定しようとしています。私のtaglibが実行されたときしかし、私はこのエラーを取得する:ロールのコレクションを遅延して初期化できませんでした:website.User.purchasedProducts、プロキシを初期化できませんでした - セッションなし

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 
    } 
} 

これだけログイン後に起こっているようですが、ユーザーが代わりに登録すると(このページにリダイレクトされると)、このエラーは発生しません。

私は自分のタグのlibsが他のものの中に入れ子になっています。

答えて

3

ログには、No sessionと書かれています。分離状態にあるオブジェクトを使用しています。したがって、オブジェクトを戻すか、idでオブジェクトをフェッチするだけです。

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

それとも

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

セッションにオブジェクトを添付しますどちらの方法。

編集

別の解決策は、熱心な負荷にhasManyの部分である可能性があります。しかし、私はドメインのフェッチを遅くするので、この解決法を好まないでしょう。また、すべての場所で必須ではないかもしれないhasManyデータを取得します。

+0

なぜこの離脱状態に入るのですか? –

+1

いろいろな理由があります。私の知る限りでは、DBに関連する操作をしようとすると、セッションを開いて閉じます。ここでフェッチしたオブジェクトは、Lazyフェッチタイプが関連付けられているHttpSessionからのものです。これは、hasManyパーツが必要なときにdatabseからロードされることを意味します。セッションがないので、データベースからのフェッチを遅延させることができません。 –

関連する問題