[英]Avoiding table changes when mapping legacy database tables in Grails?
I have an applicaton that contains some tables that are auto-generated from Grails domain classes and one legacy table (say table legacy
) that have been created outside of Grails but are being mapped by Grails domain classes. 我有一个应用程序,其中包含一些从Grails域类自动生成的表,以及一个遗留表(比如表
legacy
),这些遗留表是在Grails外部创建的,但正由Grails域类映射。 Mapping the columns in the legacy database is trivial, but I would like to disable the adding of extra fields and indexes that Grails tries to take care of for said table. 映射旧数据库中的列很简单,但是我想禁用添加额外的字段和索引,Grails会尝试为这些表添加这些字段和索引。
My question is: How do I instruct Grails not to make any table changes to the
legacy
table (changes such as adding indexes, foreign keys, version columns, etc.)? 我的问题是: 如何指示Grails不要对
legacy
表进行任何表更改(如添加索引,外键,版本列等更改)?
Please note that I do not want to disable the automatic schema generation/updating for all tables, only for the mapped table legacy
. 请注意,我不想禁用所有表的自动模式生成/更新,而只禁用映射表
legacy
。
The only way I've been able to do stuff like this is a custom Configuration class: 我能够做这样的事情的唯一方法是自定义Configuration类:
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;
}
}
Put this in src/java (it can't be written in Groovy because of a weird compilation error) and register it in DataSource.groovy using the 'configClass' attribute: 将其放在src / java中(由于奇怪的编译错误而无法用Groovy编写),然后使用'configClass'属性在DataSource.groovy中注册它:
dataSource {
pooled = true
driverClassName = ...
username = ...
password = ...
dialect = ...
configClass = com.foo.bar.DdlFilterConfiguration
}
My solution was a bit simpler. 我的解决方案要简单一些。
in the mapping section of the Domain class, I just set version false
and I named the 'id' column. 在Domain类的映射部分中,我只是将
version false
设置为version false
,并将其命名为'id'列。
class DomainClass {
static mapping = {
table 'legacyName'
version false
columns{
id column: 'legacy_id'
}
}
}
You can try using Hibernate annotations to specify things such as column name, table, etc instead of creating a normal domain class. 您可以尝试使用Hibernate注释来指定诸如列名,表等之类的内容,而不用创建普通的域类。 For more info see the "Mapping with Hibernate Annotations" section of the following link.
有关更多信息,请参见以下链接的“使用休眠注释进行映射”部分。 http://www.grails.org/Hibernate+Integration
http://www.grails.org/Hibernate+Integration
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.