3

Grails の Bootstrap.groovy (またはどこでも) でドメイン オブジェクトの ID を明示的に設定することは可能ですか?

私は次のことを試しました:

new Foo(id: 1234, name: "My Foo").save()

と:

def foo = new Foo()
foo.id = 1234
foo.name = "My Foo"
foo.save()

しかし、どちらの場合も、Foo.list()実行時に の結果を出力すると、オブジェクトに ID 1、またはシーケンス内の次の ID が与えられていることがわかります。

編集: これはGrails 1.0.3で、組み込みのHSQLデータベースを使用して「dev」でアプリケーションを実行しているときです。

編集: chanwit は以下の 1 つの優れたソリューションを提供しています。ただし、実際には、ドメインの ID 生成方法を変更せずに ID を設定する方法を探していました。これは主にテスト用です。テスト ブートストラップまたはsetUp()で特定のものを既知の id 値に設定できるようにしたいのですが、本番環境では auto_increment またはシーケンスを使用できるようにしたいと考えています。

4

3 に答える 3

10

はい、手動で GORM マッピングを使用:

class Foo {
  String name
  static mapping = {
    id generator:'assigned'
  }
}

そして、2番目のスニペット(最初のものではない)が仕事をします(コンストラクターを介して渡すときにIDは割り当てられません)。

于 2009-01-31T03:17:19.310 に答える
1

別の方法として、データをインポートするか、既存のアプリからデータを移行する場合、テスト目的で Bootstrap ファイル内のローカル マップを使用できます。メリットのある import.sql のように考えてください ;-)

このアプローチの使用:

  1. テストのためだけにドメインの制約を変更する必要はありません。
  2. 既存のデータからテスト済みの移行パスが得られます。
  3. 将来の統合テストに適したデータ スライス (または完全なスライス) が得られます

乾杯!

def init = { servletContext ->

    addFoos()
    addBars()

}

def foosByImportId = [:]
private addFoos(){
    def pattern = ~/.*\{FooID=(.*), FooCode=(.*), FooName=(.*)}/
    new File("import/Foos.txt").eachLine {
        def matcher = pattern.matcher(it)
        if (!matcher.matches()){
            return;
        }

        String fooId = StringUtils.trimToNull(matcher.group(1))
        String fooCode = StringUtils.trimToNull(matcher.group(2))
        String fooName = StringUtils.trimToNull(matcher.group(3))

        def foo = Foo.findByFooName(fooName) ?: new Foo(fooCode:fooCode,fooName:fooName).save(faileOnError:true)
        foosByImportId.putAt(Long.valueOf(fooId), foo) // ids could differ
    }
}

private addBars(){
    ...
    String fooId = StringUtils.trimToNull(matcher.group(5))
    def foo = foosByImportId[Long.valueOf(fooId)]
    ...
}
于 2012-01-25T18:26:11.140 に答える