如何使用具有 Spring 安全性和默认数据库 H2 的 Grails 数据库迁移?

How can I use Grails DB Migration with Spring Security and the default DB, H2?

我运行遇到 Grails 数据库迁移 插件生成的异常。

JIRA 中,它说这是一个不会修复的错误。

但是,我想将 Spring Security 与默认数据库 H2 一起使用,因为它易于使用做一个简单的申请。

除了将 DB 更改为 MYSQLORACLE?

之外,如何避免此错误?

更新

根据JIRA中的解决方案,我将出错的列的名称password更改为User.groovy中的passwd

下面显示 User.groovy 的一部分。

    String username
    String password
    static transients = ['springSecurityService']
    static constraints = {
        username blank: false, unique: true
        password blank: false
    }
    static mapping = {
        password column: '`passwd`'
    }

在我 运行 命令 gradle grails-dbm-gorm-diff -PgrailsArgs="2015-5-23-first-diff.groovy --add" 之后,出现如下错误。

| Starting dbm-gorm-diff
liquibase.exception.DatabaseException: org.h2.jdbc.JdbcSQLException: 列 "PASSWD" が見つかりません
Column "PASSWD" not found; SQL statement:
SELECT passwd FROM USER WHERE 1 = 0 [42122-176]
    at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.createSnapshot(JdbcDatabaseSnapshotGenerator.java:251)
    at liquibase.snapshot.DatabaseSnapshotGeneratorFactory.createSnapshot(DatabaseSnapshotGeneratorFactory.java:69)
    at liquibase.diff.Diff.compare(Diff.java:71)
    at grails.plugin.databasemigration.GormDiff.compare(GormDiff.groovy:45)
    at grails.plugin.databasemigration.ScriptUtils.createAndPrintFixedDiff(ScriptUtils.groovy:244)
    at DbmGormDiff$_run_closure1_closure2_closure3.doCall(DbmGormDiff:53)
    at grails.plugin.databasemigration.MigrationUtils.executeInSession(MigrationUtils.groovy:133)
    at DbmGormDiff$_run_closure1_closure2.doCall(DbmGormDiff:50)
    at grails.plugin.databasemigration.ScriptUtils.executeAndWrite(ScriptUtils.groovy:104)
    at DbmGormDiff$_run_closure1.doCall(DbmGormDiff:49)
    at org.grails.launcher.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:57)
    at org.grails.launcher.context.DelegatingGrailsLaunchContext.launch(DelegatingGrailsLaunchContext.java:409)
    at org.grails.launcher.ReflectiveGrailsLauncher.launch(ReflectiveGrailsLauncher.java:32)
    at org.grails.launcher.InProcessGrailsLauncher.launch(InProcessGrailsLauncher.java:27)
    at org.grails.launcher.Main.run(Main.java:62)
    at org.grails.launcher.Main.main(Main.java:38)
Caused by: org.h2.jdbc.JdbcSQLException: 列 "PASSWD" が見つかりません
Column "PASSWD" not found; SQL statement:
SELECT passwd FROM USER WHERE 1 = 0 [42122-176]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
    at org.h2.message.DbException.get(DbException.java:178)
    at org.h2.message.DbException.get(DbException.java:154)
    at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:148)
    at org.h2.command.dml.Select.prepare(Select.java:831)
    at org.h2.command.Parser.prepareCommand(Parser.java:248)
    at org.h2.engine.Session.prepareLocal(Session.java:442)
    at org.h2.engine.Session.prepareCommand(Session.java:384)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1188)
    at org.h2.jdbc.JdbcStatement.executeQuery(JdbcStatement.java:75)
    at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.isColumnAutoIncrement(JdbcDatabaseSnapshotGenerator.java:842)
    at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.readColumns(JdbcDatabaseSnapshotGenerator.java:369)
    at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.createSnapshot(JdbcDatabaseSnapshotGenerator.java:244)
    ... 15 more
:grails-dbm-gorm-diff FAILED

如 JIRA 中所述,解决方案如下:

This is caused by the backticks that escape the 'password' field in the generated user class. 'password' is a reserved word in some databases so the script escapes it by default since if it's not a reserved word it has no effect. So either remove "password column: 'password'" if it isn't a reserved word, or change it to a non-reserved word without a backtick if it is, e.g. "password column: 'passwd'"

这意味着您需要编辑您的 User 域 class。

更新 您的域 class 应该如下所示:

String username
String password
static transients = ['springSecurityService']
static constraints = {
    username blank: false, unique: true
    password blank: false
}
static mapping = {
    // NOTICE THE FOLLOWING FIELD DOES NOT HAVE BACKTICKS!
    password column: 'passwd'
}

我也 运行 遇到了这个问题,但能够通过更改来解决它:

grails dbm-gorm-diff ...

grails test dbm-gorm-diff ...

我的开发环境(默认)设置为使用 H2 数据库,但我的测试环境(此命令适用的环境)设置为使用 postgres。