1

多対多の関係を調整するために、連想テーブルをグレイルで作成することについて質問があります。設定は次のとおりです。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)
}

  }

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:クラス[classmgr.AB]の名前[a_id]のプロパティが見つかりません

私の質問はこれです:最初に、私はこれを正しく設定しましたか?次に、もしそうなら、PKがDomainAとDomainBのコンポジットで構成されているABテーブルをクエリするにはどうすればよいですか?

助けてくれてありがとう。

ジェイソン

4

1 に答える 1

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

次に、hasManyがそこにあるかのように、userInstance.authoritesのようなことを行うことができます。基本的に、あなたはGrailsがあなたのために典型的にすることをしている。しかし、これは実際には良いことです。Grailsでの収集は、正しく行われないとコストがかかる可能性があります。これは、バッグを使用して2.0で対処されています。

于 2011-08-04T21:00:05.500 に答える