使用Jongo和MongoDB在Jackson反序列化中将ObjectId _id重命名为id

时间:2014-08-26 18:06:47

标签: java mongodb playframework-2.0 jackson jongo

我刚刚开始使用play框架,jongo和MongoDB开发项目。该项目最初是在Play 2.1中用pojos编写的,其中String id字段注释为:@Id和@ObjectId这将作为ObjectId持久保存到Mongo,并且当反序列化时将id输出为:" id": " 53fcb9ede4b0b18314098d10"例如。

自升级到Jongo 1.1和Play 2.3.3以来,id属性总是被命名为" _id"反序列化时,我希望该属性保留字段名称但我不能使用@JsonProperty(" custom_name")作为Jongo @Id注释执行@JsonProperty(" _id"在幕后。

import org.jongo.marshall.jackson.oid.Id;
import org.jongo.marshall.jackson.oid.ObjectId;

public class PretendPojo {

    @Id
    @ObjectId
    private String id;

    private String name;

    public PretendPojo() {
    }

    public PretendPojo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

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

如果我通过RoboMongo查看它们,那么在MongoDB中保留的POJO看起来像这样

{
    "_id" : ObjectId("53fc984de4b0c34f1905b8ee"),
    "name" : "Owen"
}

然而,当我反序列化它们时,如果我保留两个注释,我会得到以下json:

{"name":"Owen","_id":{"time":1409072858000,"date":1409072858000,"timestamp":1409072858,"new":false,"timeSecond":1409072858,"inc":308487737,"machine":-458223042}}

以及以下输出,如果我只使用@Id注释。

{"name":"Owen","_id":"53fcbedae4b0123e12632639"}

我有一个测试用例,用于处理上面的PretendPojo节目:

   @Test
    public void testJongoIdDeserialization() throws UnknownHostException {
        DB database = new MongoClient("localhost", 27017).getDB("jongo");
        Jongo jongo = new Jongo(database);
        MongoCollection collection = jongo.getCollection("jongo");
        collection.save(new PretendPojo("Owen"));
        PretendPojo pretendPojo = collection.findOne("{name:   \"Owen\"}").as(PretendPojo.class);
        JsonNode json = Json.toJson(pretendPojo);
        assertNotNull(json.get("id"));
    }

当尝试使用自定义反序列化器时,我永远无法掌握对象ID,我似乎只能访问当前正在反序列化的日期/时间/时间戳数据。

理想情况下,我正在寻找的输出是:

  {"name":"Owen","id":"53fcbedae4b0123e12632639"}

任何帮助将不胜感激! :)

4 个答案:

答案 0 :(得分:3)

ObjectIdSerializer总是将使用@ObjectId映射的属性写入ObjectId的新实例。将此属性映射到String时,这是错误的。

为了避免这种行为,我编写了NoObjectIdSerializer:

public class NoObjectIdSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeString(value);
    }
}

像这样使用:

@ObjectId
@JsonSerialize(using = NoObjectIdSerializer.class)
protected final String _id;

an open issue

答案 1 :(得分:0)

我认为jackson中有一个注释允许你更改属性名称,我认为是:@JsonProperty但你可以在这个链接中看到所有可能的注释:

https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

我希望这能解决你的问题

答案 2 :(得分:0)

您可以尝试使用@JsonValue,Jongo does not seem来使用它们,但如果没有开发人员的任何响应,此行为可能会在将来的版本中发生变化。

@JsonValue
public Map<String, Object> getJson() {
    Map<String, Object> map = new HashMap<>();
    map.put("name", name);
    map.put("id", id);
    return map;
}

更合适的解决方案是尝试将@JsonView@Id注释结合起来 请记住指定在Jongo的ObjectMapper和您的Jackson ObjectMapper上使用哪个View(我假设在REST层中使用的那个)

@Id
@JsonView(Views.DatabaseView.class)
private String id;

@JsonView(Views.PublicView.class)
public String getId() {
    return id;
}

答案 3 :(得分:0)

自1.1以来,Jongo的行为发生了变化,以便更加一致地处理其拥有的注释。

如果你的&#39; _id&#39;是一个字符串,你希望这个字段作为字符串存储到Mongo中,然后只需要@Id。

String属性上的@Id + @ObjectId表示:

&#34;我的String属性名为&#39; foo&#39;是一个有效的ObjectId。此属性必须以名称&#39; _id&#39;存储。并且必须作为ObjectId处理。&#34;