2017-01-11 1 views
1

Beim Definieren einer eindeutigen Integritätsbedingung für eine Domänenklasse generiert Grails für die Datenbank einen Constraint-Namen, der auf dem Eigenschaftsnamen basiert. Wenn Postgres als Datenbank verwendet wird, lautet der Name 'unique_language' für die folgende Abhängigkeitsdefinition.Generierung doppelter eindeutiger Constraint-Namen

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

Wenn ich jetzt eine zweite Domäne Klasse habe, die auf einem Grundstück mit dem gleichen Namen mit dem Namen ‚unique_language‘ erstellen, Grails erneut eine Datenbank Einschränkung auch eine eindeutige Einschränkung hat. Das Problem ist, dass für Postgres der Name für eine eindeutige Einschränkung auch für das Datenbankschema eindeutig sein muss. Dies bedeutet in unserem Fall, dass die zweite Bedingung nicht auf die Datenbank angewendet wird.

Gibt es eine Möglichkeit, die eindeutigen Indexnamen anzupassen oder zu definieren?

Ich habe gesucht, ob es möglich ist, die NamingStrategy zu verbessern, aber ich konnte keinen Punkt finden, wo die Änderungen vorgenommen werden.

Wir sind derzeit Grails 2.4.4

+0

dies kann Ihnen einen Anhaltspunkt http://stackoverflow.com/questions/35220475/spring-boot-hibernate-grails-ignores-ddlauto -in-yml-Datei Problem hier diskutiert http://StackOverflow.com/Questions/28168611/postgres-unique-constraint-on-Index-does-not-work – Vahid

+1

@Vahid: Ich glaube nicht, dass dies das gleiche Problem ist . Hier besteht das Problem, dass die Namen der eindeutigen Constraints für die gesamte Datenbank eindeutig sein müssen, aber grails oder hibernate nur den Schlüssel wie folgt erzeugt: 'unique_propertyname'. Dies schlägt offensichtlich fehl, wenn Sie mehrere Domänenklassen mit denselben Eigenschaften haben und alle über eindeutige Einschränkungen verfügen. – deflomu

Antwort

1

Wir in unserem Fall verwenden Grails 2.4.4 und daher implementiert jetzt eine Abhilfe.

Wir haben einen neuen Dialekt implementiert, der von der Klasse org.hibernate.dialect.PostgreSQL9Dialect erbt.

Die einzige Änderung in der neuen Dialektklasse ist die Zuweisung eines benutzerdefinierten UnitqueDelegate namens PostgresUniqueDelegate. Diese Klasse erbt von org.hibernate.dialect.unique.DefaultUniqueDelegate und überschreibt die Methoden für die Constrainterzeugung. Hier

class PostgresSQL9DialectUniqueConstraints extends PostgreSQL9Dialect { 

    private final UniqueDelegate uniqueDelegate 

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

    @Override 
    UniqueDelegate getUniqueDelegate() { 
     return uniqueDelegate 
    } 

} 
+0

Können Sie den Code für PostgresUniqueDelegate auch veröffentlichen? – deflomu

0

ist der Code für die PostgresUniqueDelegate Klasse

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

}