5

私は、play フレームワーク、jongo、および MongoDB を使用してプロジェクトに取り組み始めました。このプロジェクトは最初、@Id と @ObjectId の両方で注釈が付けられた String id フィールドを持つ pojo を使用して Play 2.1 で作成されました。 .

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;
    }
}

MongoDB に永続化された POJO は、RoboMongo 経由で表示すると、次のようになります。

{
    "_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

@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 に答える
0

Jongo の動作は、1.1 以降、独自のアノテーションのより一貫した処理のために変更されました。

「_id」が文字列で、このフィールドを文字列として Mongo に格納する場合は、@Id のみが必要です。

String プロパティの @Id + @ObjectId は次のことを意味します。

「'foo' という名前の文字列プロパティは有効な ObjectId です。このプロパティは '_id' という名前で保存し、ObjectId として処理する必要があります。」

于 2014-10-02T13:15:22.177 に答える