开发者

Avoiding table changes when mapping legacy database tables in Grails?

开发者 https://www.devze.com 2022-12-15 07:22 出处:网络
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

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. Mapping the columns 开发者_C百科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.

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.)?

Please note that I do not want to disable the automatic schema generation/updating for all tables, only for the mapped table legacy.


The only way I've been able to do stuff like this is a custom Configuration class:

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:

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.

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. For more info see the "Mapping with Hibernate Annotations" section of the following link. http://www.grails.org/Hibernate+Integration

0

精彩评论

暂无评论...
验证码 换一张
取 消