2017-01-11 8 views
1

При определении уникального ограничения для класса домена grails генерирует для базы данных имя-ограничение, основанное на имени свойства. При использовании Postgres в качестве базы данных имя будет «unique_language» для следующего определения ограничения.Генерация повторяющихся уникальных имен ограничений

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

Когда у меня теперь есть второй класс домена, который имеет также уникальное ограничение на свойство с таким же именем, Grails снова создать базу данных ограничений с именем «unique_language». Проблема в том, что для Postgres имя для уникального ограничения также должно быть уникальным для схемы базы данных. Это означает, что в нашем случае второе ограничение не применяется к базе данных.

Есть ли способ настроить или определить уникальные имена индексов?

Я смотрел, можно ли улучшить NamingStrategy, но я не мог найти точку, где можно было бы сделать изменения.

настоящее время мы используем Grails 2.4.4

+0

это может дать вам ключ http://stackoverflow.com/questions/35220475/spring-boot-hibernate-grails-ignores-ddlauto -in-yml-файл обсуждался здесь http://stackoverflow.com/questions/28168611/postgres-unique-constraint-on-index-does-not-work – Vahid

+1

@vahid: Я не думаю, что это та же проблема , Здесь проблема в том, что имена уникальных ограничений должны быть уникальными для всей базы данных, но grails или hibernate просто создает такой ключ: 'unique_propertyname'. Это, очевидно, терпит неудачу, если у вас есть несколько классов домена со свойствами, которые называются одинаковыми и что все имеют уникальные ограничения. – deflomu

ответ

1

Мы используем в нашем случае Grails 2.4.4 и поэтому в настоящее время реализованы обходной путь.

Мы внедрили новый диалект, который наследуется от класса org.hibernate.dialect.PostgreSQL9Dialect.

Единственное изменение в новом классе диалектов - это назначение пользовательского UnitqueDelegate с именем PostgresUniqueDelegate. Этот класс наследует от org.hibernate.dialect.unique.DefaultUniqueDelegate и перезаписывает методы генерации ограничений.

class PostgresSQL9DialectUniqueConstraints extends PostgreSQL9Dialect { 

    private final UniqueDelegate uniqueDelegate 

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

    @Override 
    UniqueDelegate getUniqueDelegate() { 
     return uniqueDelegate 
    } 

} 
+0

Не могли бы вы также опубликовать код для PostgresUniqueDelegate? – deflomu

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

} 
Смежные вопросы