如何在MongoDB GORM中支持嵌入式地图(带有自定义值类型)?

时间:2012-08-12 12:01:28

标签: mongodb grails gorm

我希望有一个地图引用的嵌入式文档(如下面的“A类”)。环境是Grails + GORM + MongoDB。

是可能的,如果可以,怎么样?

class A { // fails with IllegalArgumentException occurred when processing request: can't serialize class X in line 234 of org.bson.BasicBSONEncoder
    static mapWith = "mongo"
    Map<String, X> map = new HashMap<String, X>()
}

class B { // works
    static mapWith = "mongo"
    List<X> list = new ArrayList<X>()
}

class C { // works with primitive type values
    static mapWith = "mongo"
    Map<String, String> map = new HashMap<String, String>()
}

class X {
    String data

    public X(String data) {
        this.data = data
    }
}

2 个答案:

答案 0 :(得分:3)

嵌入式工作非常完美,正如Art Hanzel所建议的那样。

但是,您的问题来自于您尝试使用List genericity作为一种约束:

Map<String, X>

问题是Grails无法很好地处理这种语法,首先是因为Groovy doesn't support genericity

但是,MongoDB插件提供了一个非常强大的功能,允许您将自定义类型定义为域类属性:see here

在你的情况下你可以

class A {
    static mapWith = "mongo"
    MyClass map = new MyClass()
}

然后在你的src / java例如,你可以实现一个

class MyClass extends HashMap<String,X> { }

然后,当然,您必须定义一个特殊的AbstractMappingAwareCustomTypeMarshaller来指定如何在DB中读取和写入属性。

另外一个步骤也可以是在A类中添加自定义验证器以检查数据的有效性......

答案 1 :(得分:0)

MongoDB Grails插件documentation描述了如何制作嵌入式文档:

class Foo {
    Address address
    List otherAddresses
    static embedded = ['address', 'otherAddresses']
}

在我的头顶,你应该能够通过对象图访问这些。我没有看到任何理由你不应该这样做。

myFoo.address.myAddressProperty...