我正在尝试“运行应用”我的Grails应用,但当它开始通过BootStrap添加用户和管理员时它会给我这个错误
Creating admin user
Fresh Database. Creating ADMIN user.
2017-12-05 19:20:48.191 ERROR --- [ main] o.g.events.gorm.GormAnnotatedListener : Error triggering event [org.grails.datastore.mapping.engine.event.PreInsertEvent[source=org.grails.orm.hibernate.HibernateDatastore@6491006]] for listener [public void com.wolf.UserPasswordEncoderListener.onPreInsertEvent(org.grails.datastore.mapping.engine.event.PreInsertEvent)]: Property [password] is not a valid property of class com.wolf.User
java.lang.IllegalArgumentException: Property [password] is not a valid property of class com.wolf.User
at org.grails.datastore.mapping.reflect.FieldEntityAccess$FieldEntityReflector.getPropertyWriter(FieldEntityAccess.java:279)
at org.grails.datastore.mapping.reflect.FieldEntityAccess.setProperty(FieldEntityAccess.java:90)
at org.grails.datastore.mapping.engine.ModificationTrackingEntityAccess.setProperty(ModificationTrackingEntityAccess.groovy:41)
at com.wolf.UserPasswordEncoderListener.encodePasswordForEvent(UserPasswordEncoderListener.groovy:31)
at com.wolf.UserPasswordEncoderListener.onPreInsertEvent(UserPasswordEncoderListener.groovy:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216)
at org.grails.events.gorm.GormAnnotatedListener$Trait$Helper.dispatch(GormAnnotatedListener.groovy:39)
at com.wolf.UserPasswordEncoderListener.dispatch(UserPasswordEncoderListener.groovy)
at org.grails.events.gorm.GormEventDispatcher.onPersistenceEvent(GormEventDispatcher.groovy:52)
at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:51)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.grails.datastore.gorm.events.ConfigurableApplicationContextEventPublisher.publishEvent(ConfigurableApplicationContextEventPublisher.groovy:30)
at org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.publishEvent(ClosureEventTriggeringInterceptor.java:258)
at org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.onPreInsert(ClosureEventTriggeringInterceptor.java:166)
at org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:197)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:75)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:623)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:277)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:303)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.onSaveOrUpdate(ClosureEventTriggeringInterceptor.java:126)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:638)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi$_performSave_closure3.doCall(AbstractHibernateGormInstanceApi.groovy:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:54)
at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:124)
at com.sun.proxy.$Proxy123.doInHibernate(Unknown Source)
at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:299)
at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:243)
at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:117)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.performSave(AbstractHibernateGormInstanceApi.groovy:242)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.save(AbstractHibernateGormInstanceApi.groovy:159)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$save$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at com.wolf.User.save(User.groovy)
at com.wolf.User.save(User.groovy)
at org.grails.datastore.gorm.GormEntity$save.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at hubbub.BootStrap.createAdminUserIfRequired(BootStrap.groovy:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:158)
at hubbub.BootStrap$_closure1.doCall(BootStrap.groovy:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1087)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:535)
at grails.util.Environment.executeForEnvironment(Environment.java:528)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:504)
at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:74)
at org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:65)
at org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:53)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:261)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
at grails.boot.GrailsApp.run(GrailsApp.groovy:387)
at grails.boot.GrailsApp.run(GrailsApp.groovy:374)
at grails.boot.GrailsApp$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at hubbub.Application.main(Application.groovy:8)
当我安装Spring Security Core Plugin并使用“passwordHash”更改我的域“User”属性“password”时,就会发生这种情况。 这是用户域:
package com.wolf
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
class User implements Serializable {
String loginId
String passwordHash
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Date dateCreated
static transients = ['springSecurityService']
static hasOne = [ profile: Profile ]
static hasMany = [ posts: Post, tags: Tag, following: User ]
Set<Role> getAuthorities() {
(UserRole.findAllByUser(this) as List<UserRole>)*.role as Set<Role>
}
static constraints = {
loginId size: 3..20, unique: true, blank: false
tags()
posts()
profile nullable: true
}
static mapping = {
posts sort: "dateCreated", order: "desc"
}
String toString() { return "User $loginId (id: $id)" }
String getDisplayString() { return loginId }
}
最后,这是BootStrap代码:
import static java.util.Calendar.*
class BootStrap {
def springSecurityService
def init = { servletContext ->
environments {
development {
if (!Post.count()) createSampleData()
}
test {
if (!Post.count()) createSampleData()
}
}
// Admin user is required for all environments
createAdminUserIfRequired()
}
private createSampleData() {
println "Creating sample data"
def now = new Date()
def chuck = new User(
loginId: "chuck_norris",
passwordHash: springSecurityService.encodePassword("highkick"),
profile: new Profile(fullName: "Chuck Norris", email: "chuck@nowhere.net"),
dateCreated: now).save(failOnError: true)
def glen = new User(
loginId: "glen",
passwordHash: springSecurityService.encodePassword("sheldon"),
profile: new Profile(fullName: "Glen Smith", email: "glen@nowhere.net"),
dateCreated: now).save(failOnError: true)
def peter = new User(
loginId: "peter",
passwordHash: springSecurityService.encodePassword("mandible"),
profile: new Profile(fullName: "Peter Ledbrook", email: "peter@nowhere.net"),
dateCreated: now).save(failOnError: true)
def frankie = new User(
loginId: "frankie",
passwordHash: springSecurityService.encodePassword("testing"),
profile: new Profile(fullName: "Frankie Goes to Hollywood", email: "frankie@nowhere.net"),
dateCreated: now).save(failOnError: true)
def sara = new User(
loginId: "sara",
passwordHash: springSecurityService.encodePassword("crikey"),
profile: new Profile(fullName: "Sara Miles", email: "sara@nowhere.net"),
dateCreated: now - 2).save(failOnError: true)
def phil = new User(
loginId: "phil",
passwordHash: springSecurityService.encodePassword("thomas"),
profile: new Profile(fullName: "Phil Potts", email: "phil@nowhere.net"),
dateCreated: now)
def dillon = new User(loginId: "dillon",
passwordHash: springSecurityService.encodePassword("crikey"),
profile: new Profile(fullName: "Dillon Jessop", email: "dillon@nowhere.net"),
dateCreated: now - 2).save(failOnError: true)
chuck.addToFollowing(phil)
chuck.addToPosts(content: "Been working my roundhouse kicks.")
chuck.addToPosts(content: "Working on a few new moves. Bit sluggish today.")
chuck.addToPosts(content: "Tinkering with the hubbub app.")
chuck.save(failOnError: true)
phil.addToFollowing(frankie)
phil.addToFollowing(sara)
phil.save(failOnError: true)
phil.addToPosts(content: "Very first post")
phil.addToPosts(content: "Second post")
phil.addToPosts(content: "Time for a BBQ!")
phil.addToPosts(content: "Writing a very very long book")
phil.addToPosts(content: "Tap dancing")
phil.addToPosts(content: "Pilates is killing me")
phil.save(failOnError: true)
sara.addToPosts(content: "My first post")
sara.addToPosts(content: "Second post")
sara.addToPosts(content: "Time for a BBQ!")
sara.addToPosts(content: "Writing a very very long book")
sara.addToPosts(content: "Tap dancing")
sara.addToPosts(content: "Pilates is killing me")
sara.save(failOnError: true)
dillon.addToPosts(content: "Pilates is killing me as well")
dillon.save(failOnError: true, flush: true)
// We have to update the 'dateCreated' field after the initial save to
// work around Grails' auto-timestamping feature. Note that this trick
// won't work for the 'lastUpdated' field.
def postsAsList = phil.posts as List
postsAsList[0].addToTags(user: phil, name: "groovy")
postsAsList[0].addToTags(user: phil, name: "grails")
postsAsList[0].dateCreated = now.updated(year: 2004, month: MAY)
postsAsList[1].addToTags(user: phil, name: "grails")
postsAsList[1].addToTags(user: phil, name: "ramblings")
postsAsList[1].addToTags(user: phil, name: "second")
postsAsList[1].dateCreated = now.updated(year: 2007, month: FEBRUARY, date: 13)
postsAsList[2].addToTags(user: phil, name: "groovy")
postsAsList[2].addToTags(user: phil, name: "bbq")
postsAsList[2].dateCreated = now.updated(year: 2009, month: OCTOBER)
postsAsList[3].addToTags(user: phil, name: "groovy")
postsAsList[3].dateCreated = now.updated(year: 2011, month: MAY, date: 1)
postsAsList[4].dateCreated = now.updated(year: 2011, month: DECEMBER, date: 4)
postsAsList[5].dateCreated = now.updated(year: 2012, date: 10)
phil.save(failOnError: true)
postsAsList = sara.posts as List
postsAsList[0].dateCreated = now.updated(year: 2007, month: MAY)
postsAsList[1].dateCreated = now.updated(year: 2008, month: APRIL, date: 13)
postsAsList[2].dateCreated = now.updated(year: 2008, month: APRIL, date: 24)
postsAsList[3].dateCreated = now.updated(year: 2011, month: NOVEMBER, date: 8)
postsAsList[4].dateCreated = now.updated(year: 2011, month: DECEMBER, date: 4)
postsAsList[5].dateCreated = now.updated(year: 2012, month: AUGUST, date: 1)
sara.dateCreated = now - 2
sara.save(failOnError: true)
dillon.dateCreated = now - 2
dillon.save(failOnError: true, flush: true)
}
private createAdminUserIfRequired() {
println "Creating admin user"
if (!User.findByLoginId("admin")) {
println "Fresh Database. Creating ADMIN user."
def profile = new Profile(email: "admin@yourhost.com", fullName: "Administrator")
def adminRole = new Role(authority: "ROLE_ADMIN").save(failOnError: true)
def adminUser = new User(
loginId: "admin",
passwordHash: springSecurityService.encodePassword("secret"),
profile: profile,
enabled: true).save(failOnError: true)
UserRole.create adminUser, adminRole, true
}
else {
println "Existing admin user, skipping creation"
}
}
}
我不知道它是否与数据库迁移插件有关,但我检查了每个域,没有人将“密码”作为属性。
答案 0 :(得分:0)
我发现解决方案......在“main / groovy / package / UserPasswordEncoderListener”中,“encorePasswordForEvent”方法使用旧属性“password”而不是“passwordHash”。
以下是使用旧“密码”属性的方法:
private void encodePasswordForEvent(AbstractPersistenceEvent event) {
if (event.entityObject instanceof User) {
User u = event.entityObject as User
if (u.passwordHash && ((event instanceof PreInsertEvent) || (event instanceof PreUpdateEvent && u.isDirty('password')))) {
event.getEntityAccess().setProperty('password', encodePassword(u.passwordHash))
}
}
}
这是新的“passwordHash”属性:
private void encodePasswordForEvent(AbstractPersistenceEvent event) {
if (event.entityObject instanceof User) {
User u = event.entityObject as User
if (u.passwordHash && ((event instanceof PreInsertEvent) || (event instanceof PreUpdateEvent && u.isDirty('passwordHash')))) {
event.getEntityAccess().setProperty('passwordHash', encodePassword(u.passwordHash))
}
}
}