我必须为PostgreSQL版本10.1实现Grails 3.3.0 Web界面作为数据库和spring-security-core版本3.2.0。
我在Linux笔记本电脑上安装了PostgreSQL,并使用Postgres用户创建了webInterfaceDev数据库。
但是,每次我想启动项目时都会收到错误"对象引用未保存的瞬态实例"。
这是我得到的错误:
2017-11-23 11:26:55.634 ERROR --- [ main] o.s.boot.SpringApplication : Application startup failed
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.domain.auth.User
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:279)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:462)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:153)
at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:2051)
at org.hibernate.loader.Loader.bindParameterValues(Loader.java:2020)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1950)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1903)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1881)
at org.hibernate.loader.Loader.doQuery(Loader.java:925)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doList(Loader.java:2622)
at org.hibernate.loader.Loader.doList(Loader.java:2605)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2434)
at org.hibernate.loader.Loader.list(Loader.java:2429)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363)
at org.grails.orm.hibernate.query.AbstractHibernateQuery.listForCriteria(AbstractHibernateQuery.java:716)
at org.grails.orm.hibernate.query.AbstractHibernateQuery.list(AbstractHibernateQuery.java:706)
at org.grails.datastore.gorm.finders.FindAllByFinder.invokeQuery(FindAllByFinder.java:54)
at org.grails.datastore.gorm.finders.FindAllByFinder$1.doInSession(FindAllByFinder.java:48)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
at org.grails.datastore.gorm.finders.AbstractFinder.execute(AbstractFinder.java:42)
at org.grails.datastore.gorm.finders.FindAllByFinder.doInvokeInternal(FindAllByFinder.java:45)
at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:254)
at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:392)
at org.grails.datastore.gorm.finders.FinderMethod$invoke$0.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:141)
at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:185)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.staticMethodMissing(GormEntity.groovy:756)
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 groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1446)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:899)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
at com.domain.auth.UserRole.staticMethodMissing(UserRole.groovy)
at com.domain.auth.UserRole.$static_methodMissing(UserRole.groovy)
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.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1499)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1487)
at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:53)
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 com.domain.auth.User.getAuthorities(User.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.MethodMetaProperty$GetBeanMethodMetaProperty.getProperty(MethodMetaProperty.java:76)
at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:85)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
at web_interface.BootStrap$_closure1.doCall(BootStrap.groovy:9)
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 web_interface.Application.main(Application.groovy:8)
FAILURE: Build failed with an exception.
以下是我使用的代码:
的grails-app / CONF / application.yml
---
grails:
profile: web
codegen:
defaultPackage: web_interface
spring:
transactionManagement:
proxies: false
gorm:
reactor:
# Whether to translate GORM events into Reactor events
# Disabled by default for performance reasons
events: false
info:
app:
name: '@info.app.name@'
version: '@info.app.version@'
grailsVersion: '@info.app.grailsVersion@'
spring:
main:
banner-mode: "off"
groovy:
template:
check-template-location: false
# Spring Actuator Endpoints are Disabled by Default
endpoints:
enabled: false
jmx:
enabled: true
---
grails:
mime:
disable:
accept:
header:
userAgents:
- Gecko
- WebKit
- Presto
- Trident
types:
all: '*/*'
atom: application/atom+xml
css: text/css
csv: text/csv
form: application/x-www-form-urlencoded
html:
- text/html
- application/xhtml+xml
js: text/javascript
json:
- application/json
- text/json
multipartForm: multipart/form-data
pdf: application/pdf
rss: application/rss+xml
text: text/plain
hal:
- application/hal+json
- application/hal+xml
xml:
- text/xml
- application/xml
urlmapping:
cache:
maxsize: 1000
controllers:
defaultScope: singleton
converters:
encoding: UTF-8
views:
default:
codec: html
gsp:
encoding: UTF-8
htmlcodec: xml
codecs:
expression: html
scriptlets: html
taglib: none
staticparts: none
endpoints:
jmx:
unique-names: true
---
hibernate:
cache:
queries: false
use_second_level_cache: false
use_query_cache: false
dataSource:
pooled: true
jmxExport: true
#mem database driver and password
#driverClassName: org.h2.Driver
#username: sa
#password:
#PostgreSQL driver and password
driverClassName: org.postgresql.Driver
username: postgres
password: password
environments:
development:
dataSource:
dbCreate: update #use create-drop or update
#Use for mem database
#url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
#Use for PostgreSQL database
url: jdbc:postgresql://localhost:5432/webInterfaceDev
test:
dataSource:
dbCreate: update
url: jdbc:postgresql:webInterfaceDev
production:
dataSource:
dbCreate: update
url: jdbc:postgresql:webInterfaceDev
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
以下是build.gradle代码:
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.2"
}
}
version "0.1"
group "web_interface"
apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"asset-pipeline"
apply plugin:"org.grails.grails-gsp"
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
//plugins needed to make the user system
compile 'org.grails.plugins:spring-security-core:3.2.0'
compile 'org.grails.plugins:spring-security-ui:3.1.1'
//end of the plugins needed
//postgresql
compile 'org.postgresql:postgresql:42.1.4.jre7'
//end
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-web-boot"
compile "org.grails:grails-logging"
compile "org.grails:grails-plugin-rest"
compile "org.grails:grails-plugin-databinding"
compile "org.grails:grails-plugin-i18n"
compile "org.grails:grails-plugin-services"
compile "org.grails:grails-plugin-url-mappings"
compile "org.grails:grails-plugin-interceptors"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:async"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:events"
compile "org.grails.plugins:hibernate5"
compile "org.hibernate:hibernate-core:5.1.5.Final"
compile "org.grails.plugins:gsp"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
runtime "org.glassfish.web:el-impl:2.1.2-b03"
runtime "com.h2database:h2"
runtime "org.apache.tomcat:tomcat-jdbc"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.14.2"
testCompile "org.grails:grails-gorm-testing-support"
testCompile "org.grails.plugins:geb"
testCompile "org.grails:grails-web-testing-support"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
}
bootRun {
jvmArgs('-Dspring.output.ansi.enabled=always')
addResources = true
}
assets {
minifyJs = true
minifyCss = true
}
以下是User.groovy代码:
package com.domain.auth
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Set<Role> getAuthorities() {
(UserRole.findAllByUser(this) as List<UserRole>)*.role as Set<Role>
}
static constraints = {
password nullable: false, blank: false, password: true
username nullable: false, blank: false, unique: true
}
static mapping = {
table '`User`' //user is properity for postgresql insted i use now User as table name
password column: '`password`'
}
}
Bootstrap.groovy代码:
package web_interface
import com.domain.auth.*
//class BootStrap {
// def passwordEncoder
//
// def init = { servletContext ->
// def adminRole = Role.findOrSaveWhere(authority:"ROLE_ADMIN")
// def user = User.findOrSaveWhere(username:"admin", password: "password").save(flush: true)
// if(!user.authorities.contains(adminRole)){
// UserRole.create(user,adminRole,true)
// }
// }
// def destroy = {
// }
//}
class BootStrap{
def init = { servletContext ->
if(User.count() == 0){
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush:true)
def admin = new User(username: 'admin', password: 'password').save(flush:true)
UserRole.create admin, adminRole
// as we call to create, flush the session explicitly ..
UserRole.withSession {
it.flush()
it.clear()
}
// instead you can put >
// new UserRole(admin, adminRole).save(flush:true)
// Do more stuff with admin user
}
}
def destroy = {
}
}
UserRole.groovy代码:
package com.domain.auth
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
import org.codehaus.groovy.util.HashCodeHelper
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {
private static final long serialVersionUID = 1
User user
Role role
@Override
boolean equals(other) {
if (other instanceof UserRole) {
other.userId == user?.id && other.roleId == role?.id
}
}
@Override
int hashCode() {
int hashCode = HashCodeHelper.initHash()
if (user) {
hashCode = HashCodeHelper.updateHash(hashCode, user.id)
}
if (role) {
hashCode = HashCodeHelper.updateHash(hashCode, role.id)
}
hashCode
}
static UserRole get(long userId, long roleId) {
criteriaFor(userId, roleId).get()
}
static boolean exists(long userId, long roleId) {
criteriaFor(userId, roleId).count()
}
private static DetachedCriteria criteriaFor(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}
}
static UserRole create(User user, Role role, boolean flush = false) {
def instance = new UserRole(user: user, role: role)
instance.save(flush: flush)
instance
}
static boolean remove(User u, Role r) {
if (u != null && r != null) {
UserRole.where { user == u && role == r }.deleteAll()
}
}
static int removeAll(User u) {
u == null ? 0 : UserRole.where { user == u }.deleteAll() as int
}
static int removeAll(Role r) {
r == null ? 0 : UserRole.where { role == r }.deleteAll() as int
}
static constraints = {
user nullable: false, unique: true
role nullable: false, validator: { Role r, UserRole ur ->
if (ur.user?.id) {
if (UserRole.exists(ur.user.id, r.id)) {
return ['userRole.exists']
}
}
user.save()
}
}
static mapping = {
id composite: ['user', 'role']
version false
}
}
Role.groovy代码:
package com.domain.auth
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
@EqualsAndHashCode(includes='authority')
@ToString(includes='authority', includeNames=true, includePackage=false)
class Role implements Serializable {
private static final long serialVersionUID = 1
String authority
static constraints = {
authority nullable: false, blank: false, unique: true
}
static mapping = {
cache true
}
}
答案 0 :(得分:1)
简短的故事
您的User.findOrSaveWhere(username:"admin", password:"password")
是问题所在。如果您在没有password:"password"
的情况下尝试,则会在启动user.password='password'
时考虑设置密码new User
。
数据库中保存的密码经过哈希处理,与您指定的密码不匹配。因此,每次运行应用时,都找不到匹配的用户,并尝试保存新用户,但username
违反了unique
约束。
Deatils -
我尝试使用以下代码 -
def xadminRole = Role.findOrSaveWhere(authority:"XYZROLE_XADMIN")
def xuser = User.findOrSaveWhere(username:"xxzadmin", password:"password")
if(!xuser.authorities.contains(xadminRole)){
UserRole.create(xuser,xadminRole,true)
}
第一次工作正常并插入User
我第二次运行应用程序时,我的用户实例出现以下错误
Field error in object 'com.xxx.ovr.User' on field 'username': rejected value [xxzadmin]; codes [[username,class com.xxx.ovr.User,xxzadmin]; default message [Property [{0}] of class [{1}] with value [{2}] must be unique]
最后
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.xxx.ovr.User
用户密码 -
$2a$10$b1Ybjt9.XVgkDi.HRgGgpeyL7WsSFMFl0jpSWy60JfTfTDNRQH/Fu
$2a$10$8HTYeE8uJgmMzclc0lku5euUpNfqa3RUZeBBs7XaJ9Z5CpT/0Prtq
所以你找不到一个带有普通密码的user
- '密码',它在散列后保存在数据库中(上面给出的例子)。要使用用户名和密码匹配用户,您可以查看帖子 -
spring security encode password with bcrypt algorithm
Grails Spring-Security -how to compare passwords-
<强>更新强>
借助@ BurtBeckwith的有用评论,我更正了“哈希”取代“加密”的答案
对于密码哈希算法,请查看1.2和3.3.2部分 https://grails-plugins.github.io/grails-spring-security-core/latest/
相关文章
Using BCrypt password hashing with Spring Security Grails plugin
对于Hash
和Encryption
之间的差异,请检查
Difference between Hashing a Password and Encrypting it
Fundamental difference between Hashing and Encryption algorithms
答案 1 :(得分:0)
在Bootstrap.groovy
中,尝试下面的简单内容
def init = { servletContext ->
if(User.count() == 0){
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush:true)
def admin = new User(username: 'admin', password: 'testpassed').save(flush:true)
UserRole.create admin, adminRole
// as we call to create, flush the session explicitly ..
UserRole.withSession {
it.flush()
it.clear()
}
// instead you can put >
// new UserRole(admin, adminRole).save(flush:true)
// Do more stuff with admin user
}
}
只需要一件小事,将db url
放入application.yml
url: jdbc:postgresql://localhost:5432/yourDBName