我有一个应用程序,其中包含一些从 Grails 域类自动生成的表和一个legacy
在 Grails 之外创建但由 Grails 域类映射的遗留表(比如 table )。映射遗留数据库中的列是微不足道的,但我想禁用 Grails 尝试为所述表处理的额外字段和索引的添加。
我的问题是:如何指示 Grails 不要对表进行任何表更改legacy
(例如添加索引、外键、版本列等更改)?
请注意,我不想禁用所有表的自动模式生成/更新,仅适用于映射表legacy
。
我有一个应用程序,其中包含一些从 Grails 域类自动生成的表和一个legacy
在 Grails 之外创建但由 Grails 域类映射的遗留表(比如 table )。映射遗留数据库中的列是微不足道的,但我想禁用 Grails 尝试为所述表处理的额外字段和索引的添加。
我的问题是:如何指示 Grails 不要对表进行任何表更改legacy
(例如添加索引、外键、版本列等更改)?
请注意,我不想禁用所有表的自动模式生成/更新,仅适用于映射表legacy
。
我能够做这样的事情的唯一方法是自定义配置类:
package com.foo.bar;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
public class DdlFilterConfiguration extends GrailsAnnotationConfiguration {
private static final String[] IGNORE_NAMES = { "legacy" };
@Override
public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
return prune(super.generateSchemaCreationScript(dialect), dialect);
}
@Override
public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
return prune(super.generateDropSchemaScript(dialect), dialect);
}
@Override
public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata) throws HibernateException {
return prune(super.generateSchemaUpdateScript(dialect, databaseMetadata), dialect);
}
private String[] prune(String[] script, Dialect dialect) {
if (dialect instanceof HSQLDialect) {
// do nothing for test env
return script;
}
List<String> pruned = new ArrayList<String>();
for (String command : script) {
if (!isIgnored(command)) {
pruned.add(command);
}
}
return pruned.toArray(new String[pruned.size()]);
}
private boolean isIgnored(String command) {
command = command.toLowerCase();
for (String table : IGNORED_NAMES) {
if (command.startsWith("create table " + table + " ") ||
command.startsWith("alter table " + table + " ") ||
command.startsWith("drop table " + table + " ")) {
return true;
}
}
return false;
}
}
将它放在 src/java 中(由于奇怪的编译错误,它不能用 Groovy 编写)并使用 'configClass' 属性在 DataSource.groovy 中注册它:
dataSource {
pooled = true
driverClassName = ...
username = ...
password = ...
dialect = ...
configClass = com.foo.bar.DdlFilterConfiguration
}
我的解决方案有点简单。
在 Domain 类的映射部分,我刚刚设置version false
并命名了“id”列。
class DomainClass {
static mapping = {
table 'legacyName'
version false
columns{
id column: 'legacy_id'
}
}
}
您可以尝试使用 Hibernate 注释来指定列名、表等内容,而不是创建普通的域类。有关详细信息,请参阅以下链接的“使用 Hibernate Annotations 映射”部分。 http://www.grails.org/Hibernate+Integration