5

我刚刚开始使用 play 框架、jongo 和 MongoDB 开展一个项目。该项目最初是在 Play 2.1 中编写的,带有带有注释的字符串 id 字段的 pojos:@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 查看 POJO,则在 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

4 回答 4

3

ObjectIdSerializer始终将使用 @ObjectId 映射的属性写入 ObjectId 的新实例。当您将此属性映射到字符串时,这是错误的。

为了避免这种行为,我写了一个 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;

一个未解决的问题

于 2014-09-03T11:09:16.200 回答
0

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

如果您的 '_id' 是一个字符串,并且您希望将此字段作为字符串存储到 Mongo 中,则只需要 @Id。

字符串属性上的@Id + @ObjectId 意味着:

“我的名为 'foo' 的字符串属性是一个有效的 ObjectId。此属性必须以名称 '_id' 存储,并且必须作为 ObjectId 处理。”

于 2014-10-02T13:15:22.177 回答
0

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

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

我希望这能解决你的问题

于 2014-08-27T12:08:23.497 回答
0

您可以尝试使用@JsonValue,Jongo似乎没有使用它们,但是如果没有开发人员的任何回应,这种行为可能会在未来的版本中发生变化。

@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 上使用哪个视图(我想是在 REST 层中使用的那个)

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

@JsonView(Views.PublicView.class)
public String getId() {
    return id;
}
于 2014-08-28T12:29:46.103 回答