在Grails中映射旧数据库表时避免表更改?

时间:2009-12-30 23:41:31

标签: grails gorm

我有一个应用程序包含一些从Grails域类自动生成的表和一个遗留表(比如表legacy),它们是在Grails之外创建的,但是由Grails域类映射。映射遗留数据库中的列是微不足道的,但我想禁用添加Grails尝试为所述表进行处理的额外字段和索引。

我的问题是:如何指示Grails不要对legacy表进行任何表更改(诸如添加索引,外键,版本列等更改) 。)?

请注意,我不想为所有表禁用自动架构生成/更新,仅针对映射表legacy

3 个答案:

答案 0 :(得分:3)

我能够做这样的事情的唯一方法是自定义配置类:

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
}

答案 1 :(得分:3)

我的解决方案有点简单。

在Domain类的映射部分中,我只设置了version false并命名为'id'列。

class DomainClass {
    static mapping = {
        table 'legacyName'
        version false
        columns{
            id column: 'legacy_id'
        }
    }
}

答案 2 :(得分:0)

您可以尝试使用Hibernate注释来指定列名,表等内容,而不是创建普通的域类。有关详细信息,请参阅以下链接中的“使用Hibernate Annotations进行映射”部分。 http://www.grails.org/Hibernate+Integration