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 数据库在“开发”中运行我的应用程序时。

编辑: chanwit 在下面提供了一个很好的解决方案。但是,我实际上是在寻找一种在不更改域的 id 生成方法的情况下设置 id 的方法。这主要用于测试:我希望能够在我的测试引导程序中将某些东西设置为已知的 id 值setUp(),但仍然能够在生产中使用 auto_increment 或序列。

4

3 回答 3

10

是的,使用手动 GORM 映射:

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

并且您的第二个片段(不是第一个片段)将完成这项工作(通过构造函数传递它时不会分配 ID)。

于 2009-01-31T03:17:19.310 回答
1

我最终使用的解决方法是不尝试通过对象的 ID 检索对象。因此,对于问题中给出的示例,我更改了域对象:

class Foo {
  short code /* new field */
  String name

  static constraints = {
    code(unique: true)
    name()
  }
}

然后我使用 anenum来保存代码的所有可能值(它们是静态的),并通过使用适当的枚举值Foo执行 a 来检索对象(而不是像我之前想要的那样使用 id)。Foo.findByCode()Foo.get()

这不是最优雅的解决方案,但它对我有用。

于 2009-03-06T17:07:07.990 回答
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 回答