我已经在config.groovy中添加了一个onAuthenticationSuccessEvent,以便尝试将Login模型添加到用户User模型中的列表中。我遇到的问题是,事件监听器是一个闭包,因此没有HibernateSession或访问闭包之外的状态。
我知道可以通过这样做来绑定HibernateSession:
grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx ->
Login.withTransaction{
login = new Login()
}
}
问题是Login属于User,需要在其构造函数中定义User。如何将用户传递到闭包中?
我想做类似的事情:
def user = grails.admin.User.read(appCtx.springSecurityService.currentUser.id)
Login.withTransaction{ user ->
login = new Login(user: user)
}
但不知道如何传递特定用户。
答案 0 :(得分:1)
您不能执行Login.withTransaction{ user ->
,因为传递给withTransaction
方法的闭包参数采用的是TransactionStatus
参数 - 您无法指定类型,只是名字。
但是我不确定为什么你会看到关于闭合范围你所看到的。关闭闭包很酷的事情是它们包含它们的范围,因此名称。所以闭包之外的变量总是在闭包内部可用。
您希望在User
块中加载withTransaction
,因为它与事务处于相同的Hibernate会话中,否则Login
保存将失败,因为{{1}将被断开连接。并且使用User
,而不是load()
,因为您只是在read()
中设置了外键,因此Login
效果最好,因为它只创建了一个代理并且没有命中数据库,但使load()
保存的ID可用。出于同样的原因,您希望避免使用Login
方法,因为它只是currentUser
的快捷方式。
说了这么多,这对我有用:
User.get()
但由于grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx ->
Login.withTransaction { status ->
new Login(user: appCtx.springSecurityService.currentUser).save()
}
}
变量为e
,您最好使用此功能:
InteractiveAuthenticationSuccessEvent
答案 1 :(得分: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)
}