Reputation: 119
Having generated a User, Role, and UserRole classes using the s2-quickstart script of spring security I now want to add fields to the user class, such as email.
My User class contains:
//User.groovy
String username
String password
String email
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
All seems to work until as I followed the tutorial in the documention I did the following
//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
This yielded the output:
|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
Cheers
==Edit==
As requested by dmahapatro here is my UserRole Class, not edited from the generated model
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
}
}
==Edit 2==
By request of Sérgio Michels, having done his sugestions it prints the following:
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]
Upvotes: 0
Views: 1496
Reputation: 597
That's probably because your domain class User
or Role
contains au property id
.
This id
property is used in UserRole
.
This is not allow because Grails Spring Plugin used a parameter name id
.
In Grails spring plugin the type of this parameter is long.
Solution :
Change the name of your property from id
to uuid
. or delete the property.
Exemple :
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)
}
hope that help.
Upvotes: 0
Reputation:
That's probably because your user creation failed, and you're not validating it. Try to change your BootStrap to:
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)
If it fails, change to print the errors:
adminUser.validate()
println adminUser.errors
My guess is that you didn't add the email in the validations block, making this mandatory.
Upvotes: 2