带有数据库迁移插件的 Grails 3:在 Grails 应用程序之外使用 class [com.mypackage.security.RequestMap] 上的方法

Grails 3 with database-migration plugin: Method on class [com.mypackage.security.RequestMap] was used outside of a Grails application

我正在使用带有 database-migration 插件的 Grails 3.0.7。我有超级简单的迁移,我无法开始工作:

databaseChangeLog = {
    changeSet(id: '20150926BaseSecurityConfig', author: 'me') {
        grailsChange {
            change {
                    new RequestMap('/home', 'permitAll').save(failOnError: true, flush: true)
            }
        }
    }
}

仅此而已。我在 运行 Grails 2.3.7 的另一个项目中进行了类似的迁移,没有任何问题。在这里,我得到这个例外:

Caused by: java.lang.IllegalStateException: Method on class [com.mysite.security.RequestMap] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)

此外,如果我将 new RequestMap 行放在 BootStrap.groovy 中,它会保存得很好。我不确定这里的问题是什么。

插件需要认真修改,大部分声明无效。

始终使用 XML 和原生 SQL。它完美运行:

<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet author="me" id="201510201650_ins_data_into_foo_bar">
        <sql>
            INSERT INTO foo.bar(code, name) VALUES(1, 'demo');
            INSERT INTO foo.bar(code, name) VALUES(2, 'demo2');
        </sql>
        <rollback>
            DELETE FROM foo.bar WHERE code BETWEEN 1 AND 2;
        </rollback>
    </changeSet>

</databaseChangeLog>

我使用 SQL 语句进行数据库迁移。

databaseChangeLog = {

        changeSet(author: "me", id: "20150926BaseSecurityConfig") {

            preConditions(onFail: 'MARK_RAN', onFailMessage: 'RequestMap already exists' ){
                sqlCheck(expectedResult: '0', "SELECT count(*) FROM request_map WHERE url = '/home' and configAttribute = 'permitAll'")
            }

            sql("""
                    INSERT INTO request_map(url, configAttribute)
                    VALUES ('/home', 'permitAll')
            """)
        }
    }
<?xml version="1.0" encoding="UTF-8"?>    
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet author="me" id="20150926BaseSecurityConfig">
        <sql>
            INSERT INTO request_map(url, configAttribute)
    SELECT v.url, v.c FROM (SELECT '/home' as url, 'permitAll' as c) as v
           WHERE NOT EXISTS(SELECT m.* FROM request_map as m 
                         WHERE m.url = v.url AND m.configAttribute = v.c);
        </sql>
        <rollback>
            DELETE FROM request_map WHERE url LIKE '/home' AND configAttribute LIKE 'permitAll';
        </rollback>
    </changeSet>

</databaseChangeLog>