生成重复的唯一约束名称

时间:2017-01-11 13:22:21

标签: postgresql grails gorm grails-2.0

在为域类定义唯一约束时,grails为数据库生成一个基于属性名称的约束名称。 当使用Postgres作为数据库时,名称将是" unique_language'用于以下约束定义。

   static constraints = {
      language nullable: false, unique: 'product'
   }

当我现在有第二个域类,它对具有相同名称的属性也有唯一约束时,grails将再次使用名称" unique_language'创建数据库约束。 问题是,对于Postgres,唯一约束的名称对于数据库模式也必须是唯一的。这意味着在我们的情况下,第二个 约束不适用于数据库。

有没有办法自定义或定义唯一索引名称?

我在寻找是否有可能增强NamingStrategy,但我无法找到改变的地方。

我们目前正在使用grails 2.4.4

3 个答案:

答案 0 :(得分:1)

此问题已在Grails 3.1.0.RC2中修复:https://github.com/grails/grails-data-mapping/issues/623

答案 1 :(得分:1)

我们在我们的案例中使用grails 2.4.4,因此现在实现了一种解决方法。

我们实施了一种新的方言,它继承自班级org.hibernate.dialect.PostgreSQL9Dialect

新方言类中唯一的变化是分配一个名为PostgresUniqueDelegate的自定义UnitqueDelegate。该类继承自org.hibernate.dialect.unique.DefaultUniqueDelegate并覆盖约束生成的方法。

class PostgresSQL9DialectUniqueConstraints extends PostgreSQL9Dialect {

    private final UniqueDelegate uniqueDelegate

    PostgresSQL9DialectUniqueConstraints() {
        super()
        uniqueDelegate = new PostgresUniqueDelegate(this)
    }

    @Override
    UniqueDelegate getUniqueDelegate() {
        return uniqueDelegate
    }

}

答案 2 :(得分:0)

以下是PostgresUniqueDelegate类的代码

class PostgresUniqueDelegate extends DefaultUniqueDelegate {

    PostgresUniqueDelegate(Dialect dialect) {
        super(dialect)
    }

    private final PREFIX = "unique_"

    private String getCustomUniqueKey(String uniqueKeyName, String tableName) {
        return uniqueKeyName.replaceAll(PREFIX, PREFIX + tableName + "_")
    }

    @Override
    String getAlterTableToAddUniqueKeyCommand(
            org.hibernate.mapping.UniqueKey uniqueKey,
            String defaultCatalog,
            String defaultSchema)
    {
        // Do this here, rather than allowing UniqueKey/Constraint to do it.
        // We need full, simplified control over whether or not it happens.
        final String tableName = uniqueKey.getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema)
        final String constraintName = dialect.quote(getCustomUniqueKey(uniqueKey.getName(), tableName))
        return "alter table " + tableName + " add constraint " + constraintName + " " + uniqueConstraintSql(uniqueKey)
    }

    @Override
    String getAlterTableToAddUniqueKeyCommand(UniqueKey uniqueKey) {
        // Do this here, rather than allowing UniqueKey/Constraint to do it.
        // We need full, simplified control over whether or not it happens.
        final String tableName = uniqueKey.getTable().getQualifiedName(dialect)
        final String constraintName = dialect.quote(getCustomUniqueKey(uniqueKey.getName(), tableName))

        return "alter table " + tableName + " add constraint " + constraintName + uniqueConstraintSql(uniqueKey);
    }

}