Grails 3.3.0使用postgresql 10.1作为数据库,spring-security-core为"对象引用了一个未保存的瞬态实例"错误

时间:2017-11-23 10:47:11

标签: postgresql grails gorm

我必须为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
    }
}

2 个答案:

答案 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

对于HashEncryption之间的差异,请检查

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