2011-08-04 4 views
1

J'ai une question sur la création d'une table associative, dans grails, pour réconcilier une relation many-to-many. La configuration est la suivante: 1. Le domaine A (profil client) peut avoir plusieurs domaines B (amis) 2. Chaque domaine B (amis) peut avoir plusieurs domaines A (profil client) 3. Pour résoudre ce problème, je dois créer une table associative (ou domaine) qui a des FK de chaque table. Ce domaine peut être nommé Domaine C (client_friend)Grails Domain Créer une table d'association

Voici le code que j'ai jusqu'à présent:

class DomainA{ 
    String id 
String firstName 
String lastName 
    static hasMany = [domainB: DomainB] 
    static mapping = { 
    cache true 
    id generator: 'assigned' 

    columns { 
     firstName type:'text' 
     lastName type:'text' 
     alumConnections column: 'domaina_id', joinTable: 'a_b' 
    } 

} 
static constraints = { 
    firstName (nullable:true) 
    lastName (nullable:true) 
} 

    } 

code DomaineB:

class DomainB{ 
String id 
String firstName 
String lastName 

    static hasMany = [domainA:DomainA] 
static belongsTo = DomainA 
static mapping = { 
    cache true 
    id generator: 'assigned'   

      columns {     
     firstName  type:'text' 
     lastName  type:'text' 
     domainA column: 'domainb_id', joinTable: 'a_b' 
    } 
} 
static constraints = { 
    firstName  (nullable:true) 
    lastName  (nullable:true) 

} 
    } 

Domaine Code A_B:

class AB{ 


Date dateCreated 
Date lastUpdated 
long version 

    } 

Lorsque je lance ce code, cela semble fonctionner. Les tables, en utilisant MySQL, sont créées, FK semble être en place. Lorsque je saisis des données dans la classe DomainB, les données sont saisies et les PK de DomainA et DomainB sont insérés dans A_B. Mais, les problèmes viennent quand j'essaye de supprimer des valeurs de A_B. J'ai essayé quelque chose comme ceci:

 AB results =AB.findByAIdAndBId('jIi-hRi4cI','2BYvuA2X14') 

mais je reçois une erreur: InvalidPropertyException: Aucun bien trouvé pour nom [a_id] pour la classe [classe mgr.AB]

Ma question est la suivante: en premier lieu, ont Je l'ai mis en place correctement? Deuxièmement, si oui, comment puis-je interroger la table AB qui PK est composé d'un composite de DomainA et DomainB?

Merci pour toute aide.

jason

Répondre

1

Votre classe composite n'est pas tout à fait correct. Regardez cet exemple et ajustez le vôtre en conséquence. Voici comment je fais tous mes domaines composites:

class UserRole implements Serializable { 

    User user 
    Role role 

    boolean equals(other) { 
     if (!(other instanceof UserRole)) { 
      return false 
     } 

     other.user?.id == user?.id && 
      other.role?.id == role?.id 
    } 

    int hashCode() { 
     def builder = new HashCodeBuilder() 
     if (user) builder.append(user.id) 
     if (role) builder.append(role.id) 
     builder.toHashCode() 
    } 

    static UserRole get(long userId, long roleId) { 
     find 'from UserRole where user.id=:userId and role.id=:roleId', 
      [userId: userId, roleId: roleId] 
    } 

    static UserRole create(User user, Role role, boolean flush = false) { 
     new UserRole(user: user, role: role).save(flush: flush, insert: true) 
    } 

    static boolean remove(User user, Role role, boolean flush = false) { 
     UserRole instance = UserRole.findByUserAndRole(user, role) 
     instance ? instance.delete(flush: flush) : false 
    } 

    static void removeAll(User user) { 
     executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user] 
    } 

    static void removeAll(Role role) { 
     executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role] 
    } 

    static mapping = { 
     id composite: ['role', 'user'] 
     version false 
    } 
} 

Une fois que vous avez, il n'y a pas besoin de les belongsTo et hasMany. Mais pour accéder aux données de ces domaines, vous pouvez fournir des méthodes telles que les suivantes:

class User { 

    // typical domain junk 

    Set<Role> getAuthorities() { 
    UserRole.findAllByUser(this).collect { it.role } as Set 
    } 
} 

Ensuite, vous pouvez faire des choses comme userInstance.authorites comme si le hasMany était là. Fondamentalement, vous faites ce que Grails ferait pour vous. Mais c'est en fait une bonne chose. Les collections de Grails peuvent être coûteuses si elles ne sont pas bien faites. Ceci est adressé en 2.0 avec l'utilisation de sacs.

+0

Nous vous remercions de votre réponse. Qu'en est-il, dans mon exemple, DomainA et DomainB? Ai-je besoin de me débarrasser de leur «appartient à» et «a beaucoup»? – jason

+0

Oui, il n'y a pas besoin d'eux. Je vais mettre à jour ma réponse pour réfléchir à la façon de gérer cela. – Gregg

+0

Merci, je vais mettre en œuvre ces changements et voir comment cela fonctionne! – jason