Grails域创建关联表

时间:2011-08-04 19:24:42

标签: hibernate grails grails-domain-class grails-controller

我有一个关于在grails中创建关联表以协调多对多关系的问题。设置是这样的: 1.域A(客户端配置文件)可以有很多域B(朋友) 2.每个域B(朋友)可以拥有多个域A(客户端配置文件) 3.要解决这个问题,我需要创建一个从每个表中都有FK的关联表(或域)。该域名可以命名为Domain C(client_friend)

这是我到目前为止的代码:

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

  }

DomainB代码:

   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)

}
  }

域名A_B代码:

 class AB{


Date dateCreated
Date lastUpdated
long version

  }

当我运行此代码时,它似乎工作。使用MySQL创建的表格,FK似乎已经到位。当我将数据输入DomainB类时,输入数据,并将来自DomainA和DomainB的两个PK插入到A_B中。但是,当我尝试从A_B中删除值时会出现问题。我尝试过这样的事情:

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

但是收到错误:InvalidPropertyException:找不到类[类mgr.AB]的名称[a_id]的属性

我的问题是:首先,我是否正确设置了这个?第二,如果是这样,那我怎么查询AB表谁的PK由DomainA和DomainB的复合组成?

感谢您的帮助。

杰森

1 个答案:

答案 0 :(得分:1)

您的复合课程并不完全正确。看看这个例子并相应地调整你的例子。这就是我所有复合域的方式:

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

一旦有了,就不需要belongsTo和hasMany关联。但是要从这些域访问数据,您可以提供以下方法:

class User {

   // typical domain junk

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

然后你可以像userInstance.authorites这样做,就像hasMany在那里一样。基本上,你正在做Grails典型的事情。但这实际上是一件好事。如果做得不对,Grails中的集合可能会很昂贵。这在2.0中通过使用袋来解决。