2012-02-14 11 views
0

ユーザモデル内のリストにログインモデルを追加しようとすると、config.groovyにonAuthenticationSuccessEventを追加しました。私が抱えている問題は、イベントリスナーがクロージャであり、HibernateSessionやクロージャの外側にある状態へのアクセスがないことです。Springセキュリティ内のGroovyモデルを永続化するイベントリスナー

私はこのような何かを行うことによってHibernateSessionを結合するためにその可能性を知っている:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction{ 
     login = new Login() 
    } 
} 

問題はログインがユーザーに属し、そのコンストラクタで定義されたユーザーを持っている必要があるということです。どのように私は閉鎖にユーザーを渡すのですか?

私のような何かをしたい:

def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
Login.withTransaction{ user -> 
    login = new Login(user: user) 
} 

をしかし、中に特定のユーザーを渡す方法を知らない

答えて

1

あなたはwithTransactionメソッドに渡すクロージャのパラメータがTransactionStatusある引数を取るので、あなたはLogin.withTransaction{ user ->を行うことはできません - あなたはタイプを指定するために得ることはありません、ちょうど名前。

しかし、閉鎖の範囲に関してあなたが目にしていることがなぜ分かっているのか分かりません。閉鎖についての涼しいことは、の範囲、したがって名前を囲むということです。したがって、クロージャの外側の変数は、クロージャの内部で常に使用可能です。それは、トランザクションのと同じHibernateセッション中だけれども

あなたはそうLoginUserが切断されますので、保存は失敗します、UserwithTransactionブロック内でロードするとよいでしょう。外部キーをLoginに設定するだけなので、load()ではなくread()を使用してください。load()はプロキシを作成してデータベースにヒットしないため、の保存でIDを使用できるので最適です。同様の理由から、User.get()のショートカットにすぎないので、currentUserメソッドの使用は避けたいと考えています。

はすべてのことを言って、これは私の仕事:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction { status -> 
     new Login(user: appCtx.springSecurityService.currentUser).save() 
    } 
} 

しかしe変数がInteractiveAuthenticationSuccessEventあるので、これを使用して方がいいでしょう:

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx -> 
    Login.withTransaction { status -> 
     def user = User.load(e.authentication.principal.id) 
     new Login(user: user).save() 
    } 
} 
0

あなたは以下のようないくつかのことを行うことができないのはなぜ、すぐ内側ユーザーをフェッチします。閉鎖。

Login.withNewSession { 
    def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
    login = new Login(user: user) 
} 

OR

Login.withTransaction{ 
    def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id) 
    login = new Login(user: user) 
} 
+0

私はそのためのやるカントをクロージャー内のユーザーを参照することができない同じ理由 - クロージャーにはイベントハンドラーの残りのスコープがないため、appCtxオブジェクトもクロージャー内でnullです。私は "nullのオブジェクトのプロパティ 'currentUser'を取得できません。だから、私はどちらかのクロージャをユーザーまたはappCtx属性として渡す必要がありますが、どのように知っている。 –

関連する問題