2010-08-10 3 views
1

Je rencontre des problèmes en utilisant des contraintes uniques. Les combinaisons suivantes sont autoriséesUnicité de l'ID composite avec le composant null

A.name B.name 
foo  NULL 
foo  bar 
foo  bar1 
foo1 bar 

Il ne devrait pas être possible de créer un nouveau A avec le même nom, que si elle a un autre B. Avec les contraintes ci-dessous, il est possible de créer

A.name B.name 
foo NULL 
foo NULL 

Parce que NULL ne semble pas avoir d'effet sur unique.

Des conseils pour résoudre ce problème?

class A { 
    String name 
    static belongsTo = [b:B] 
    static constraints = { 
    name(unique:'b') 
    b(nullable:true) 
    } 
} 

class B { 
    String name 
    static hasMany = [as:A] 
    name(unique:true) 
} 
+0

Quel (s) SGBDR utilisez-vous? –

+0

mysql, mais la question aimes à résoudre dans grails et sa contrainte pour les domaines – skurt

+0

null valeurs int composant clé peut vous conduire à de sérieux problèmes: s'il vous plaît envisager de ne pas autoriser la valeur nulle dans le composant clé. Sérieusement: ne pas autoriser la valeur NULL dans le composant clé – Sammyrulez

Répondre

1

Dans la structure de base de données, vous pouvez définir les colonnes à NOT NULL DEFAULT 0 ou similaire, puis traiter les zéros les mêmes que vous le feriez autrement les NULLs? Puisque la colonne est pour les noms, il n'y a probablement pas de chiffres dans les valeurs, n'est-ce pas?

+0

Pourquoi 0 au lieu de '' –

+0

Certains (ou au moins un, Oracle) RDBMS traitent '''' comme 'null'. –

+0

À quoi correspondent les définitions de classe ci-dessus dans SQL? Pourrions-nous voir les définitions de la table, s'il vous plaît? –

1

Je ne suis pas tout à fait sûr, mais je pense que cela va fonctionner:

name(unique:['b', 'name']) 

En regardant le code de la contrainte unique, il semble possible. La contrainte vous permet définitivement de passer une liste de choses pour comparer l'unicité à. Il appelle cela l'unicitéGroup. Ensuite, lors de la validation, il itère sur cette liste. Jetez un oeil à partir de la ligne 137 ici: http://www.docjar.com/html/api/org/codehaus/groovy/grails/orm/hibernate/validation/UniqueConstraint.java.html

Le code ressemble à ceci:

if(shouldValidate) { 
    Criteria criteria = session.createCriteria(constraintOwningClass) 
     .add(Restrictions.eq(constraintPropertyName, propertyValue)); 
    if(uniquenessGroup != null) { 
     for(Iterator it = uniquenessGroup.iterator(); it.hasNext();) { 
      String propertyName = (String) it.next(); 
      criteria.add(Restrictions.eq(propertyName, 
        GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(target, propertyName))); 
     } 
    } 
    return criteria.list(); 
} 

Cela dépend si l'appel GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue récupérera une propriété dans la même classe. Lequel, basé sur le nom, il semble qu'il devrait le faire.

Je suis curieux de savoir si cela fonctionne pour vous.

+0

Non cela ne fonctionne pas. Il est toujours possible de créer deux As avec le même nom et NULL comme B – skurt

Questions connexes