Домен Grails Создать таблицу сопоставлений

У меня есть вопрос о создании ассоциативной таблицы в Grails для согласования отношений "многие ко многим". Настройка такова: 1. Домен A (профиль клиента) может иметь много доменов B (друзей) 2. Каждый домен B (друзья) может иметь много доменов A (профиль клиента) 3. Чтобы решить эту проблему, мне нужно создать ассоциативный таблица (или домен), в которой есть FK из каждой таблицы. Этот домен можно назвать Домен 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)
}

  }

Код доменаB:

   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, данные вводятся, и оба PK из DomainA и DomainB вставляются в A_B. Но проблемы возникают, когда я пытаюсь удалить значения из A_B. Я пробовал что-то вроде этого:

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

но получаю сообщение об ошибке: InvalidPropertyException: свойство не найдено для имени [a_id] для класса [класс mgr.AB]

У меня такой вопрос: во-первых, правильно ли я это настроил? Во-вторых, если да, то как тогда мне запросить таблицу AB, чей PK состоит из композита DomainA и DomainB?

Спасибо за любую помощь.

Джейсон


person jason    schedule 04.08.2011    source источник


Ответы (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
    }
}

Как только вы это сделаете, вам больше не нужны будут ассоциации ownTo и hasMany. Но для доступа к данным из этих доменов вы можете предоставить следующие методы:

class User {

   // typical domain junk

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

Затем вы можете делать такие вещи, как userInstance.authorites, как если бы это было hasMany. По сути, вы делаете то, что Grails обычно делает за вас. Но на самом деле это хорошо. Коллекции в Grails могут быть дорогостоящими, если они сделаны неправильно. Это решается в версии 2.0 с помощью Bags.

person Gregg    schedule 04.08.2011
comment
Благодарю за ваш ответ. Как насчет, в моем примере, домена A и домена B? Нужно ли мне избавляться от их «принадлежит» и «имеет многие»? - person jason; 05.08.2011
comment
Да и нужды в них нет. Я обновлю свой ответ, чтобы отразить, как с этим справиться. - person Gregg; 05.08.2011
comment
Я внес эти изменения, и, кажется, все в порядке. еще раз спасибо! - person jason; 05.08.2011