2017-01-05 4 views
0

オブジェクトのマップを格納する場合は、キーと値の両方がString:Map<String,String>である必要があることをGrails/GORMのドキュメントから知っています。Grailsのドメインオブジェクト格納マップ<K,V>

このマップ内のキーとして別のドメインオブジェクト(Animal)を使用したいと思いますが、上記の制約のために不可能です。 Animalの識別子は簡単に文字列型に変換できますが、もしそれを行うなら、GORMが親オブジェクトを取得する際にマッピングを実行するのに十分スマートであるとは思いません。

誰もこれに遭遇しましたか?

答えて

1

私は、これは動作するはずだと思う:

class TestService { 
    def save(values) { 
    Test test1 = new Test() 
    test1.name='something' 
    // so to add 3 of animal objects above values would be 
    def animal1=Animal.find() 
    String key1='ANI' //For animals 
    def animal2=Monkey.find() // where Monkey extends Animal (hence the keys) 
    String key2='MON' //For monkeys only 
    test1.myAnimals[key1]=animal1 
    test1.myAnimals[key2]=animal2 
    test1.save() 

     /** 
     * When you have a real values map that contains useful method you can 
     * do it this way - left commented out FYI on manual process above 
     Test test = new Test() 
     // you now have some map of values coming in that contains a key 
     // and actual object so you could make this up if you are testing 
    values.animals?.each{k,v-> 
       test.myAnimals[k]=v 
      } 
    }  
    test.save() 
    */   
} 

だから、最初の例マッピングするために保存するときにサービスで

class Test { 
    String name 
    Map myAnimals=[:] 

    //When given a specific key it will return actual animal object 
    def findAnimal(String myKey) { 
    return myAnimals.find{it.key==myKey}?.value 
    //What above is doing can be seen broken down here: 
    //def ani = myAnimals.find{it.key==myKey} 
    //println "ANI::: ${ani} ${ani.value}" 
    //def animal = ani?.value 
    //return animal 

    } 
} 

は、マップを持っているdomainclassを持っていると仮定すると、 values.eachは、保存されているキーと実際のドメインオブジェクトを含む独自のマップを作成した場所です。

2番目のtest1の例では、テストとして渡す自動化された値を持たずに手作業で行いました。その後

あなたは(あなたがに制限され見ることができるように)実際の動物を取得するために、テストオブジェクトを持っている重要なので、一匹1匹のサル1鳥など

あなたは

Test test = Test.findByName('something) 
def animal = test.findAnimal('ANI') 
def monkey = test.findAnimal('MON') 
println "animal is ${animal} ${animal.getClass()} monkey is ${monkey} ${monkey.getClass()}" 

を持っている場合はこれが今まで見ていきますドメインクラスメソッドと呼び出しごとに動物オブジェクトを返そうとする

これを起動する前に、動物が1つ、猿が1つ以上必要です。だから私のブートストラップに:私はそれを実行すると

import test.Animal 
import test.Monkey 

class BootStrap { 

    def init = { servletContext -> 

     Animal animal = new Animal() 
     animal.name='Daffy Duck' 
     animal.save(flush:true) 
     Monkey monkey = new Monkey() 
     monkey.name='King Kong' 
     monkey.save(flush:true) 
    } 
    def destroy = { 
    } 
} 

は、私はそのprintlnから入手:

animal is class test.Animal class java.lang.Class monkey is class test.Monkey class java.lang.Class 

はまた、それを引き起こしているビット列のエラーが不明にいくつかのクラス取得 - 出力として見えるからのprintlnをあなたは望みます。

あなたは、あなたが常にAnimalオブジェクトを返すようにfindByAnimalを変えることができる鍵を保持し、そのキーのためのいくつかの他のコードを照会するには、メインクラスとして動物を使用する別の方法を選択する必要がある場合があります

//When given a specific key it will return actual animal object 
    Animal findAnimal(String myKey) { 
     Animal animal = myAnimals.find{it.key==myKey}?.value 
     return animal 
    } 

Animal、またはAnimalを拡張したMonkeyのため、コールが変更されました。上の例の2つの欠落したクラス:

package test 

class Animal { 
    String name 

} 
package test 

class Monkey extends Animal { 


} 
関連する問題