【问题标题】:Generation of duplicate unique constraint names生成重复的唯一约束名称
【发布时间】:2017-05-26 07:34:37
【问题描述】:

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

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

当我现在有了第二个域类,它对同名的属性也有唯一约束时,grails 将再次创建一个名为“unique_language”的数据库约束。 问题是,对于 Postgres,唯一约束的名称对于数据库模式也必须是唯一的。这意味着在我们的例子中,第二个 约束未应用于数据库。

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

我一直在寻找是否可以增强 NamingStrategy,但我找不到进行更改的地方。

我们目前使用的是 grails 2.4.4

【问题讨论】:

  • 这可能会给你一个线索stackoverflow.com/questions/35220475/… 这里讨论的问题stackoverflow.com/questions/28168611/…
  • @vahid:我不认为这是同一个问题。这里的问题是唯一约束的名称对于整个数据库必须是唯一的,但 grails 或 hibernate 只是创建这样的键:unique_propertyname。当您有多个属性名称相同且都具有唯一约束的域类时,这显然会失败。

标签: postgresql grails grails-orm grails-2.0


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我们在我们的案例中使用的是 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
        }
    
    }
    

    【讨论】:

    • 你能把 PostgresUniqueDelegate 的代码贴出来吗?
    【解决方案3】:

    这是 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);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 2014-11-28
      • 2011-06-17
      • 1970-01-01
      • 2017-04-07
      相关资源
      最近更新 更多