I'm having trouble extending the Spring Security User class to include a profile class. The profile class is simple and just holds a list of Strings. When I go to run the application, I'm thrown the following error, Parameter 7 is not set:
| Error 2014-03-20 22:33:26,751 [localhost-startStop-1] ERROR util.JDBCExceptionReporter - Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]
| Error 2014-03-20 22:33:26,815 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: Hibernate operation: could not insert: [ibm_cd_dashboard.User]; uncategorized SQLException for SQL [insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?)]; SQL state [90012]; error code [90012]; Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]; nested exception is org.h2.jdbc.JdbcSQLException: Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]
Message: Hibernate operation: could not insert: [ibm_cd_dashboard.User]; uncategorized SQLException for SQL [insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?)]; SQL state [90012]; error code [90012]; Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]; nested exception is org.h2.jdbc.JdbcSQLException: Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]
Line | Method
->> 28 | ensureSave in BootStrap
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 14 | doCall in BootStrap$_closure1
| 308 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 301 | executeForEnvironment in ''
| 277 | executeForCurrentEnvironment . . in ''
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . . . . . . . . . . . . in java.lang.Thread
Caused by JdbcSQLException: Parameter "#7" is not set; SQL statement:
insert into user (id, version, account_expired, account_locked, enabled, "password", password_expired, user_profile_id, username) values (null, ?, ?, ?, ?, ?, ?, ?, ?) [90012-173]
->> 331 | getJdbcSQLException in org.h2.message.DbException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 171 | get in ''
| 148 | get . . . . . . . . . . . . . . in ''
| 80 | checkSet in org.h2.expression.Parameter
| 163 | checkParameters . . . . . . . . in org.h2.command.Prepared
| 78 | update in org.h2.command.CommandContainer
| 235 | executeUpdate . . . . . . . . . in org.h2.command.Command
| 154 | executeUpdateInternal in org.h2.jdbc.JdbcPreparedStatement
| 140 | executeUpdate . . . . . . . . . in ''
| 28 | ensureSave in BootStrap
| 14 | doCall . . . . . . . . . . . . . in BootStrap$_closure1
| 308 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 301 | executeForEnvironment . . . . . in ''
| 277 | executeForCurrentEnvironment in ''
| 262 | run . . . . . . . . . . . . . . in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run in java.lang.Thread
| Error 2014-03-20 22:33:27,071 [Thread-13] ERROR hbm2ddl.SchemaExport - schema export unsuccessful
Message: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-173]
Line | Method
->> 331 | getJdbcSQLException in org.h2.message.DbException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 171 | get in ''
| 148 | get . . . . . . . . in ''
| 137 | get in ''
| 1413 | checkClosed . . . . in org.h2.jdbc.JdbcConnection
| 1388 | checkClosed in ''
| 428 | getAutoCommit . . . in ''
^ 744 | run in java.lang.Thread
User Profile:
class UserProfile {
static hasOne = [user:User]
static belongsTo = User
static constraints = {
}
static mapping = {
}
List<String> projects
}
User is basically the standard spring class:
class User {
transient springSecurityService
static hasOne = [userProfile:UserProfile]
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static transients = ['springSecurityService']
static constraints = {
username blank: false, unique: true
password blank: false
userProfile unique:true, nullable: true
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
Bootstrap:
def init = { servletContext ->
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def testUser = new User(username: 'me', password: 'password', userProfile: null)
ensureSave(testUser)
testUser.userProfile = new UserProfile(projects: null, version: null, user: testUser)
ensureSave(testUser)
UserRole.create testUser, adminRole, true
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
def ensureSave(domainObject) {
if(!domainObject.save(flush:true)) {
throw new Exception("not saved successfully: $domainObject");
}
domainObject
}
Removing the associations between the User and UserProfile class allows the application to run normally. Playing around wiht the code I've also gotten "Parameter #4 is not set". Any help appreciated.
I was able to successfully resolve this issue using the help of the comments posted by other users. Here is the updated code.
Bootstrap class BootStrap {
def init = { servletContext ->
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def testUser = new User(username: 'me', password: 'password', userProfile: new UserProfile(projects: null, version: null))
testUser.save(flush: true, failOnError: true)
UserRole.create testUser, adminRole, true
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
def destroy = {
}
}
UserProfile
class UserProfile {
static belongsTo = [user:User]
static constraints = {
}
static mapping = {
}
List<String> projects
}
User Class:
class User {
transient springSecurityService
static hasOne = [userProfile:UserProfile]
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static transients = ['springSecurityService']
static constraints = {
username blank: false, unique: true
password blank: false
userProfile unique:true, nullable: true
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}