2011-03-31 2 views
5

J'ai trois classes de domaine: Beer, Review et Reviewer. Je souhaite que la table Review crée une relation many-to-many entre Beer et Reviewer, donc je souhaite que la clé primaire de Review soit un composite des champs id de Beer et Reviewer. Je suis la documentation de Grails.Comment créer une clé primaire composite à l'aide de GORM?

http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html#5.5.2.5%20Composite%20Primary%20Keys

Voici mes classes de domaine.

class Beer { 
    String name 
    String type 
    Brewery breweryId 

    static hasMany = [ reviews : Review ] 

    static constraints = { 
    } 
} 

class Reviewer { 
    String screenName 

    static hasMany = [ reviews : Review ] 

    static constraints = { 
    } 
} 

class Review implements Serializable { 
    int score 
    Beer beer 
    Reviewer reviewer 


    static constraints = { 
    } 

    static mapping = { 
     id composite:['beer', 'reviewer'] 
    } 
} 

Je recevais des erreurs de compilation, mais une autre réponse ici sur stackoverflow dit que je devais ajouter implements Serializable. Cela a pris soin de l'erreur, mais quand je regarde dans la base de données, je ne reçois toujours pas une clé primaire composite.

Voici ce que je vois quand je regarde la définition de la table. J'utilise Postgres.

 Table "public.review" 
    Column | Type | Modifiers 
-------------+---------+----------- 
id   | bigint | not null 
version  | bigint | not null 
beer_id  | bigint | not null 
reviewer_id | bigint | not null 
score  | integer | not null 
Indexes: 
    "review_pkey" PRIMARY KEY, btree (id) 
Foreign-key constraints: 
    "fkc84ef75823f39326" FOREIGN KEY (beer_id) REFERENCES beer(id) 
    "fkc84ef7587c483106" FOREIGN KEY (reviewer_id) REFERENCES reviewer(id) 

Je serais heureux avec juste un indice composite avec une contrainte unique, mais je ne peux pas comprendre comment faire, que ce soit. J'ai réussi à créer un index composite non unique, mais cela pose deux problèmes. Un, c'est non-unique. Deuxièmement, les colonnes sont spécifiées par ordre alphabétique dans l'index (beer_id, reviewer_id). Je voudrais spécifier l'ordre des colonnes dans l'index.

Répondre

0

Essayez ce, dans votre domaine d'examen classe de domaine:

static constraints = { 
    review(unique: ['beer','reviewer']) 
} 

vous pourriez avoir besoin de laisser tomber la table et laisser Gorm le recréer. La contrainte ci-dessus signifie qu'une révision doit consister en un enregistrement unique de la combinaison bière/critique. Il est encore beaucoup à beaucoup où un critique a plusieurs bières et vice versa, mais les critiques sont uniques.

2

J'ai mis en place une situation similaire, avec quelques conditions différentes:

  1. Il n'y a aucun lien hasMany.
  2. requête à la classe de jointure est fait par HQL
  3. En utilisant une cartographie

plus détaillée lors de la mise en œuvre comme celui-ci, la base de données MySQL est ok. (beer_id, reviewer_id) est la clé primaire. Je ne sais pas quelle est la cause exacte de votre problème, mais j'espère que cela vous donnera une idée de l'endroit où le problème peut se produire.

2

J'ai pris le mandat de Grails que je ne devrais pas utiliser les clés composites primaires comme conseils judicieux et je l'évite. Si oui, je crois qu'une alternative viable pour résoudre votre problème est la contrainte unique composée. ref: http://grails.org/doc/1.1.x/ref/Constraints/unique.html

réponse de Jacco semble pas correct, mais il semble visuellement très proche de corriger, voici comment vous écririez une contrainte composite unique pour ce problème:

static constraints = { 
    beer(unique: 'reviewer') 
} 

alors que si la programmeur voulait relier 3 champs db comme unique, la formation correcte est:

static constraints = { 
    beer(unique: ['anotherField','reviewer']) 
} 

qui ressemble comme la réponse de Jacco, mais le nom de classe n'est pas utilisé comme première chaîne de la contrainte, le premier nom de champ est utilisé.

J'ai juste utilisé cette structure de code dans ma propre application de projet, et il semble se comporter correctement, voir également ceci sur la façon de tester les contraintes uniques unité: http://www.ibm.com/developerworks/java/library/j-grails10209/index.html (voir la liste 11)

Questions connexes