1

Grails ドメイン クラスから自動生成されたいくつかのテーブルと、legacyGrails の外部で作成されたが Grails ドメイン クラスによってマップされている 1 つのレガシー テーブル ( table など) を含むアプリケーションがあります。レガシーデータベースの列をマッピングするのは簡単ですが、Grailsがそのテーブルに対して処理しようとする余分なフィールドとインデックスの追加を無効にしたいと思います.

私の質問は次のとおりです。Grails にテーブルに変更を加えないlegacyようにするにはどうすればよいですか(インデックス、外部キー、バージョン列などの追加などの変更)。

すべてのテーブルの自動スキーマ生成/更新を無効にしたくないことに注意してください。マップされたテーブルに対してのみですlegacy

4

3 に答える 3

3

私の解決策はもう少し簡単でした。

ドメイン クラスのマッピング セクションで、version false「id」列を設定して名前を付けました。

class DomainClass {
    static mapping = {
        table 'legacyName'
        version false
        columns{
            id column: 'legacy_id'
        }
    }
}
于 2012-03-22T11:34:45.943 に答える
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
}
于 2009-12-31T00:00:23.167 に答える
0

通常のドメイン クラスを作成する代わりに、Hibernate アノテーションを使用して、列名、テーブルなどを指定することができます。詳細については、次のリンクの「Hibernate Annotations によるマッピング」セクションを参照してください。 http://www.grails.org/Hibernate+Integration

于 2009-12-30T23:52:53.267 に答える