在Grails(GORM)中,如何覆盖约束名称

时间:2015-04-06 01:39:18

标签: gorm

Grails(GORM)中,如何覆盖约束名称(在生成的dbm脚本中)。我正在使用Oracle和GORM。 似乎约束名称的长度限制为15.

如果没有办法覆盖那么有没有办法将长度改为15(比如说25)!!

e.g。

CREATE TABLE X ( 
       id NUMBER(19,0) NOT NULL, 
       CONSTRAINT overridden_name_here 
       PRIMARY KEY (id));   

2 个答案:

答案 0 :(得分:4)

在Grails 3中,如果您使用的是Hibernate 4.x,则只需要扩展类 HibernateMappingContextConfiguration 并覆盖 secondPassCompile 方法来自定义外键名称。但是,如果你想使用Hibernate 5,解决方案会略有不同。请参阅graeme对slack grails-community的评论:

  

不是我们的错。 Hibernate 5显着不同,所以我们不得不适应。他们基本上不赞成使用Configuration层次结构,也改变了挂钩元数据的方式。对于Hibernate 5.2,这将不得不再次改变。

因此,为了解决与Hibernate 5和Grails 3相关的这个问题,我在下面进行了实现。首先,我们需要覆盖默认的hibernate实现:

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitForeignKeyNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;

public class ReadableImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {

    public static final ReadableImplicitNamingStrategy INSTANCE = new ReadableImplicitNamingStrategy();

    private String getPlural(String tableName) {

        final int len = tableName.length();
        final boolean isLower = Character.isLowerCase(tableName.charAt(len - 1));
        final String s = tableName.toLowerCase();
        final char lastChar = s.charAt(len - 1);

        String result = tableName;

        switch (lastChar) {
            case 'y':
                result = tableName.substring(0, tableName.length() -1) + (isLower? "ie": "IE"); break;
            case 's':
            case 'x':
            case 'z':
                result = tableName.substring(0, tableName.length() -1) + (isLower? "e": "E"); break;
            default:
                if (s.endsWith("sh")) {
                    result = tableName.substring(0, tableName.length() -1) + (isLower? "e": "E");
                }
        }
        result += (isLower? "s": "S");
        return result;
    }

    @Override
    public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {

        StringBuilder sb = new StringBuilder("FK_")
                .append(source.getReferencedTableName().getText())
                .append("_")
                .append(getPlural(source.getTableName().getText()));

        return toIdentifier(sb.toString(), source.getBuildingContext());

    }
}

此外,我们必须创建一个类来自定义Gorm配置:

import org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration

    class GormConfiguration extends HibernateMappingContextConfiguration {

        @Override
        protected void reset() {
            super.reset();
            this.implicitNamingStrategy = ReadableImplicitNamingStrategy.INSTANCE;
        }

    }

最后,在我们的application.yml中引用我们将在DataSource中使用的自定义类。

dataSource:
    dbCreate: update
    configClass: mypackage.GormConfiguration

答案 1 :(得分:3)

不确定最新的Grails 3是否提供了一种更直接的自定义约束名称的方法,但在Grails 2.4.5及更早版本中,可以使用自定义配置子类。

它主要涉及通过扩展 GrailsAnnotationConfiguration 并覆盖 secondPassCompile()方法来创建自己的配置。在此方法中,您可以访问域类并访问/设置许多不同的属性,包括外键约束名称。

有关详细示例,请参阅Burt Beckwith的帖子:http://burtbeckwith.com/blog/?p=465

我认为约束名称的长度限制是由底层数据库实现决定的,而不是GORM本身。