2009-12-30 49 views
1

我有一個應用程序,其中包含一些自動生成的Grails域類和一個遺留表(表legacy),它們是在Grails之外創建的,但由Grails域類映射。映射遺留數據庫中的列是微不足道的,但我希望禁用添加額外的字段和索引,Grails會爲所述表格添加額外的字段和索引。在Grails中映射遺留數據庫表時避免表更改?

我的問題是:我怎麼教的Grails不作變化(如添加索引,外鍵,版本柱等)任何表更改legacy表?

請注意,我不想禁用所有表的自動模式生成/更新,僅限映射表legacy

回答

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 
} 
0

您可以嘗試使用Hibernate註釋來指定諸如列名,表等等之類的內容,而不是創建普通的域類。有關更多信息,請參閱以下鏈接的「映射Hibernate註釋」部分。 http://www.grails.org/Hibernate+Integration

3

我的解決方案有點簡單。

在Domain類的映射部分,我只設置了version false,並將其命名爲'id'列。

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

這可能在2009年當這個問題首次被問到時是不可能的;然而,現在肯定是正確的答案。 – Michael 2015-06-25 21:21:18

相關問題