使用spring security的s2-quickstart脚本生成User,Role和UserRole类后,我现在想要向用户类添加字段,例如电子邮件。
我的用户类包含:
//User.groovy
String username
String password
String email
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
一切似乎都有效,直到我按照文档中的教程执行以下操作
//BootStrap.goovy
def adminRole = new Role(authority:'ROLE_ADMIN').save(flush: true)
def adminUser = new User(username:'admin', password:'password')
adminUser.save(flush: true)
UserRole.create adminUser, adminRole, true
这产生了输出:
|Loading Grails 2.3.8
|Configuring classpath
.
|Environment set to development
.................................
|Packaging Grails application
...........
|Compiling 1 source files
...................................
|Running Grails application
Configuring Spring Security Core ...
... finished configuring Spring Security Core
| Error 2014-05-29 21:59:59,728 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: No signature of method: uk.co.xonos.bookings.UserRole.exists() is applicable for argument types: (null, java.lang.Long) values: [null, 1]
Possible solutions: exists(long, long), exists(java.io.Serializable), list(), first(), wait(), last()
Message: No signature of method: uk.co.xonos.bookings.UserRole.exists() is applicable for argument types: (null, java.lang.Long) values: [null, 1]
Possible solutions: exists(long, long), exists(java.io.Serializable), list(), first(), wait(), last()
Line | Method
->> 91 | methodMissing in org.grails.datastore.gorm.GormStaticApi
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 86 | doCall in uk.co.xonos.bookings.UserRole$__clinit__closure9_closure14_closure15
| 85 | doCall . . . . . . . . . . . . . in uk.co.xonos.bookings.UserRole$__clinit__closure9_closure14
| 44 | create in uk.co.xonos.bookings.UserRole
| 39 | doCall . . . . . . . . . . . . . in BootStrap$_closure1
| 308 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 301 | executeForEnvironment . . . . . in ''
| 277 | executeForCurrentEnvironment in ''
| 303 | innerRun . . . . . . . . . . . . in java.util.concurrent.FutureTask$Sync
| 138 | run in java.util.concurrent.FutureTask
| 895 | runTask . . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
| 918 | run in ''
^ 695 | run . . . . . . . . . . . . . . in java.lang.Thread
Error |
Forked Grails VM exited with error
|Server running. Browse to http://localhost:8080/Bookings
干杯
==编辑==
根据dmahapatro的要求,这是我的UserRole类,不是从生成的模型中编辑的
package uk.co.xonos.bookings
import org.apache.commons.lang.builder.HashCodeBuilder
class UserRole implements Serializable {
private static final long serialVersionUID = 1
User user
Role role
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id &&
other.role?.id == role?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static UserRole get(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}.get()
}
static boolean exists(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}.count() > 0
}
static UserRole create(User user, Role role, boolean flush = false) {
def instance = new UserRole(user: user, role: role)
instance.save(flush: flush, insert: true)
instance
}
static boolean remove(User u, Role r, boolean flush = false) {
if (u == null || r == null) return false
int rowCount = UserRole.where {
user == User.load(u.id) &&
role == Role.load(r.id)
}.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
rowCount > 0
}
static void removeAll(User u, boolean flush = false) {
if (u == null) return
UserRole.where {
user == User.load(u.id)
}.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static void removeAll(Role r, boolean flush = false) {
if (r == null) return
UserRole.where {
role == Role.load(r.id)
}.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static constraints = {
role validator: { Role r, UserRole ur ->
if (ur.user == null) return
boolean existing = false
UserRole.withNewSession {
existing = UserRole.exists(ur.user.id, r.id)
}
if (existing) {
return 'userRole.exists'
}
}
}
static mapping = {
id composite: ['role', 'user']
version false
}
}
==编辑2 ==
根据塞尔吉奥·米歇尔斯的要求,完成了他的sugestions后,打印出以下内容:
grails.validation.ValidationErrors: 1 errors
Field error in object 'uk.co.xonos.bookings.User' on field 'email': rejected value [null]; codes [uk.co.xonos.bookings.User.email.nullable.error.uk.co.xonos.bookings.User.email,uk.co.xonos.bookings.User.email.nullable.error.email,uk.co.xonos.bookings.User.email.nullable.error.java.lang.String,uk.co.xonos.bookings.User.email.nullable.error,user.email.nullable.error.uk.co.xonos.bookings.User.email,user.email.nullable.error.email,user.email.nullable.error.java.lang.String,user.email.nullable.error,uk.co.xonos.bookings.User.email.nullable.uk.co.xonos.bookings.User.email,uk.co.xonos.bookings.User.email.nullable.email,uk.co.xonos.bookings.User.email.nullable.java.lang.String,uk.co.xonos.bookings.User.email.nullable,user.email.nullable.uk.co.xonos.bookings.User.email,user.email.nullable.email,user.email.nullable.java.lang.String,user.email.nullable,nullable.uk.co.xonos.bookings.User.email,nullable.email,nullable.java.lang.String,nullable]; arguments [email,class uk.co.xonos.bookings.User]; default message [Property [{0}] of class [{1}] cannot be null]
答案 0 :(得分:2)
这可能是因为您的用户创建失败了,而您没有验证它。尝试将BootStrap更改为:
def adminRole = new Role(authority:'ROLE_ADMIN')
assert adminRole.save(flush: true)
def adminUser = new User(username:'admin', password:'password')
assert adminUser.save(flush: true)
如果失败,请更改以打印错误:
adminUser.validate()
println adminUser.errors
我的猜测是你没有在验证栏中添加电子邮件,这是强制性的。
答案 1 :(得分:0)
这可能是因为您的域类User
或Role
包含au属性id
。
此id
属性用于UserRole
。
这是不允许的,因为Grails Spring插件使用了参数名id
。
在Grails spring插件中,此参数的类型很长。
解决方案:
将您的媒体资源名称从id
更改为uuid
。或删除该属性。
例如:
def role1 = Role.findOrSaveWhere(authority: 'ROLE_ADMIN')
def defaultUser = User.findOrSaveWhere(username: 'admin', password: 'password', )
if(!defaultUser.authorities.contains(role1)){
UserRole.create(defaultUser,role1,true)
}
希望有所帮助。