Grails 2 - 无法创建弹簧安全域对象

Posted

技术标签:

【中文标题】Grails 2 - 无法创建弹簧安全域对象【英文标题】:Grails 2 - Cannot create spring security domain object 【发布时间】:2014-01-02 22:48:21 【问题描述】:

在运行 grails s2-quickstart com.testApplication.secureApplication User Role 后,我已经从 grails 插件页面安装了 spring security 应用程序,以自动生成我所做的域对象 grails run-app 并得到了这个异常:

|Loading Grails 2.3.4
|Configuring classpath
.
|Environment set to development
.................................
|Packaging Grails application
Precompiling AST Transformations ...
src C:\Users\GrailsWorkspace\testApplication\target\work\plugins\postgresql-extensions-0.6.1 C:\Users\GrailsWorkspace\testApplication\target\classes
Done precompiling AST Transformations!
..
|Compiling 3 source files
...................................................
|Running Grails application
Configuring Spring Security Core ...
... finished configuring Spring Security Core
Error |
2013-12-15 15:42:45,635 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Unsuccessful: create table user (id int8 not null, version int8 not null, account_expired bool not null, account_locked bool not null, enabled bool not null, "password" varchar(255) not null, password_expired bool not null, username varchar(255) not null unique, primary key (id))
Error |
2013-12-15 15:42:45,638 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - ERROR: syntax error at "user"
  Position: 14
Error |
2013-12-15 15:42:45,688 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Unsuccessful: alter table user_role add constraint FK143BF46A1E03E05D foreign key (user_id) references user
Error |
2013-12-15 15:42:45,688 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - ERROR: syntax error at "user"
  Position: 90
|Server running. 

问题是我的数据库配置正确,因为我得到了表roleuser_role。但是用户不会在我的postgresql db 中生成。我对自动生成的user domain object 的实现如下所示:

class User 

    transient springSecurityService

    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
    

    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)
    

感谢您的回答!

【问题讨论】:

【参考方案1】:

'user' 是 Postgres 中的保留名称。您可以通过在域类中设置映射并使用备用名称来避免这种情况。

 static mapping =  table 'myusers' 

这样您的域类保持不变。您也可以像使用“密码”一样转义名称。

【讨论】:

没想到user是关键字,谢谢!【参考方案2】:

在用户域中,添加如下映射配置,保持域/表名user类似于跳过password列的方式。

static mapping = 
    table '`user`'
    password column: '`password`'

可以找到解释问题和解决方案的博文here

【讨论】:

试过这个解决方案。它通过了第一个问题,但随后它产生了序列命名的新问题:spi.SqlExceptionHelper 错误:关系“seq_”user“”不存在我认为最好避免在 postgres 中使用名为“user”的表。 @EdJ 我没有使用任何序列命名,也没有看到这个问题。正如您所说,如果您可以避免使用名为“用户”的表,那很好,但我喜欢保留这个名称。

以上是关于Grails 2 - 无法创建弹簧安全域对象的主要内容,如果未能解决你的问题,请参考以下文章

缺少 Grails 弹簧安全插件插件?

如何绕过特定域的经过身份验证的端点上的弹簧安全性?

Grails:弹簧安全插件 - 错误 springsecurity.GormPersistentTokenRepository

具有弹簧安全性的 Grails 3.2.6。保存用户时未在内存中创建 h2 数据库

grails spring 安全角色和组

使用 grails 控制台创建的新域对象在 dbconsole 中不可见