1

考虑类:

class Person {
    String name;
    Person father;
    Person mother;
    List<Person> children;
}

有没有办法向 jongo 表明fathermother并且children应该手动引用同一集合中的其他对象而不是嵌入对象?

注意:这与DBRefs不同。

4

2 回答 2

1

还没有。

最简单的方法是手动发出第二个查询。

不过,您可以适当地创建一个 Jackson de/serializer 来在解组过程中获取文档。几个月前,我们为在解组期间获取 DBRef 创建了一个尖峰,这段代码可以提供帮助:Handle DBRef during (un)marshalling

随意添加功能请求

于 2013-02-19T08:21:01.053 回答
1

我用一种方法来处理它。不确定它是否完美,但它适用于我自己。

假设您有这些课程

public class MyObject {

    @Id
    private String id;
    private MyEmbeddedObject embeddedObject;

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public MyEmbeddedObject getEmbeddedObject() {
        return this.embeddedObject;
    }

    public void setEmbeddedObject(MyEmbeddedObject embeddedObject) {
        this.embeddedObject = embeddedObject;
    }

}


public class MyEmbeddedObject {

    @Id
    private String id;

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

您希望将 MyEmbeddedObject 存储在集合“embed”中,并将 Object 存储在集合“object”中,并手动引用“embed”集合 ID。例如 :

object : { id:1, embeddedObjectId: 99 }
embed : { id : 99 }

您可以为 MyEmbeddedObject 实现自定义序列化器和反序列化器

public class MyEmbeddedObjectSerializer extends JsonSerializer<MyEmbeddedObject> {

    @Override
    public void serialize(MyEmbeddedObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeText(value.getId());
    }
}

public class MyEmbeddedObjectDeserializer extends JsonDeserializer<MyEmbeddedObject> {

    @Override
    public MyEmbeddedObject deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        MyEmbeddedObject obj = new MyEmbeddedObject();
        obj.setId(jsonParser.getString());
        return new MyEmbeddedObject();

    }
 }

如果您在 Jongo 中注册您的序列化程序,问题是它将作为 MyObject 的成员用于 MyEmbeddedObject,但当它单独存储在“嵌入”集合中时,也用于 MyEmbeddedObject。

为了仅在 MyEmbeddedObject 嵌入 MyOBject 时应用自定义序列化器/反序列化器,我使用 Mixin 注释。

public interface MyObjectMixIn {

    @JsonSerialize(using=MyEmbeddedObjectSerializer .class)
    public MyEmbeddedObject getEmbeddedObject();

    @JsonDeserialize(using=MyEmbeddedObjectDeserializer.class)
    public void setEmbeddedObject(MyEmbeddedObject embeddedObject);

}

然后定义一个模块

public class MyModule extends SimpleModule {
    @Override
    public void setupModule(SetupContext context) {
        context.setMixInAnnotations(MyObject.class, MyObjectMixIn.class);
    }
}

最后在 Jongo 中注册模块

Jongo jongo = new Jongo(db, JacksonMapper.Builder().registerModule(new MyModule ()).build());

现在将其用于存储在 Mongo

  1. 将 embeddedObject 本身存储在集合“embed”中以获取 id
  2. 确保 object 的 embeddedObject 成员包含 id
  3. 将对象存储在集合“对象”中。仅存储嵌入对象的 id

并读取数据存储

  1. 从集合“对象”中读取对象。嵌入对象将仅使用其 ID 进行初始化
  2. 如果需要,请阅读“嵌入”集合中的嵌入对象。

编辑:为了避免延迟加载并在反序列化时加载完整的对象, Jackson 的HandlerInstantiator对象对于自定义序列化器和反序列化器构造机制很有用。

希望有帮助。

于 2013-11-05T13:56:58.170 回答