MongoDB和Java – CodecRegistry仅返回ID字段而不是POJO中的所有字段?

huangapple go评论61阅读模式
英文:

MongoDB and java - CodecRegistry only returning an ID field rather than all fields in POJO?

问题

我有以下代码来创建我的Java Spring项目中的Mongo客户端:

CodecRegistry pojoCodecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
        fromProviders(PojoCodecProvider.builder().register(Person.class).automatic(true).build()));

MongoClientSettings settings = MongoClientSettings.builder()
        .codecRegistry(pojoCodecRegistry)
        .applyConnectionString(new ConnectionString("myConnectionString"))
        .build();

MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase("person").withCodecRegistry(pojoCodecRegistry);
MongoCollection<Person> collection = database.getCollection("personCollection", Person.class).withCodecRegistry(pojoCodecRegistry);

我的Kotlin Pojo是:

@JsonInclude(JsonInclude.Include.NON_NULL)
class Person {

    @JsonProperty("_id")
    var personID: String? = null

    @JsonProperty("name")
    var type: String? = null

    @JsonProperty("age")
    var age: Int? = null

}

我能够获得响应,但响应不如预期,即它是这样的:

{
  "persons": [
    {
      "ID": "personId1"
    },
    {
      "ID": "personId2"
    },
    {
      "ID": "personId3"
    }
  ]
}

每个人对象只显示了一些ID字段,而不是我期望的POJO中的字段。

我在这里缺少什么?我需要为我的Pojo定义自定义编解码器吗?我不确定,因为我是第一次使用这个Mongo库。

英文:

I have the following code to create my mongo client in my Java Spring project:

CodecRegistry pojoCodecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
        fromProviders(PojoCodecProvider.builder().register(Person.class).automatic(true).build()));

MongoClientSettings settings = MongoClientSettings.builder()
        .codecRegistry(pojoCodecRegistry)
        .applyConnectionString(new ConnectionString(&quot;myConnectionStrng&quot;))
        .build();

MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase database = mongoClient.getDatabase(&quot;person&quot;).withCodecRegistry(pojoCodecRegistry);
MongoCollection&lt;Person&gt; collection = database.getCollection(&quot;personCollection&quot;, Person.class).withCodecRegistry(pojoCodecRegistry);

My Kotilin Pojo is:

@JsonInclude(JsonInclude.Include.NON_NULL)
class Person {

    @JsonProperty(&quot;_id&quot;)
    var personID: String? = null

    @JsonProperty(&quot;name&quot;)
    var type: String? = null

    @JsonProperty(&quot;age&quot;)
    var age: Int? = null
	
}

I am able to get a response but the response is not as expected, i.e. it is

{
  &quot;persons&quot;: [
    {
      &quot;ID&quot;: &quot;personId1&quot;
    },
    {
      &quot;ID&quot;: &quot;personId2&quot;
    },
    {
      &quot;ID&quot;: &quot;personId3&quot;
    }
}

Each person object only shows some ID field rather than the fields in my POJO that I am expecting.

What am I missing here? Do I need to define a custom codec for my Pojo? I am unsure as first time using this mongo library.

答案1

得分: 3

以下是一些工作中的代码,您可以看到我写入数据库并读取数据。

在您的问题中有几件事情不太清楚,这可能可以解释为什么您的尝试没有成功,或者我可能误解了您的需求。

Person

Person 是一个 POJO - 对于这个,您可能不希望使用一个普通的 class。在我创建的方式中,构造 Person 很麻烦 - 我不得不创建一个小的辅助方法,因为您的类中没有构造函数:

private static Person makePerson(String id, String type, int age) {
    Person p = new Person();
    p.setPersonID(id);
    p.setType(type);
    p.setAge(age);
    return p;
}

然而,如果您进行一些小的修改并使用 data class,那么这将隐式地为您提供一个构造函数、toString()hashCode()

@JsonInclude(JsonInclude.Include.NON_NULL)
data class Person (     //&lt;&lt; round brackets

    @JsonProperty(&quot;_id&quot;)
    var personID: String? = null,  //&lt;&lt; comma

    @JsonProperty(&quot;name&quot;)
    var type: String? = null,

    @JsonProperty(&quot;age&quot;)
    var age: Int? = null,

)

编解码器设置

我认为您的编解码器设置方式不正确(如果缺少编解码器,您将收到启动错误)。请查看我的工作代码。

您的预期输出是什么?

您说它与预期不符,是因为缺少了年龄和姓名/类型字段吗?字段名称也是“ID”,您想要什么?personID_id 还是 ID

您现在的输出是如何实现的?

您没有说明如何提取和显示 JSON 数据,但鉴于您使用的注解(@JsonProperty),您必须使用 Jackson,我在我的代码示例中包括了它。您提到的快速入门指南谈到了 @BsonProperty - 这是用于数据库中的字段命名的不同目的,而 @JsonProperty 用于 JSON 中的字段命名。

示例代码

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;

import java.util.ArrayList;
import java.util.List;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;

public class Test {

    public static void main(String[] args) {
        ConnectionString connectionString = new ConnectionString(&quot;mongodb://127.0.0.1:27017&quot;);
        CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
        MongoClientSettings clientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .codecRegistry(codecRegistry)
                .build();
        try (MongoClient mongoClient = MongoClients.create(clientSettings)) {
            MongoDatabase database = mongoClient.getDatabase(&quot;person&quot;);
            MongoCollection&lt;Person&gt; collection = database.getCollection(&quot;personCollection&quot;, Person.class);

            List&lt;Person&gt; persons = new ArrayList&lt;&gt;();
            persons.add(makePerson(&quot;personId1&quot;, &quot;Lesley&quot;, 10));
            persons.add(makePerson(&quot;personId2&quot;, &quot;Bob&quot;, 20));
            persons.add(makePerson(&quot;personId3&quot;, &quot;Jane&quot;, 30));

            collection.insertMany(persons);

            List&lt;Person&gt; persons2 = collection.find().into(new ArrayList&lt;Person&gt;());
            ObjectMapper mapper = new ObjectMapper();
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(persons2));

        } catch (JsonProcessingException e) {
            throw a RuntimeException(e);
        }
    }

    private static Person makePerson(String id, String type, int age) {
        Person p = new Person();
        p.setPersonID(id);
        p.setType(type);
        p.setAge(age);
        return p;
    }
}

输出是:

[ {
  &quot;_id&quot; : &quot;personId1&quot;,
  &quot;name&quot; : &quot;Lesley&quot;,
  &quot;age&quot; : 10
}, {
  &quot;_id&quot; : &quot;personId2&quot;,
  &quot;name&quot; : &quot;Bob&quot;,
  &quot;age&quot; : 20
}, {
  &quot;_id&quot; : &quot;personId3&quot;,
  &quot;name&quot; : &quot;Jane&quot;,
  &quot;age&quot; : 30
} ]

我使用的依赖项如下:

        &lt;dependency&gt;
            &lt;groupId&gt;org.mongodb&lt;/groupId&gt;
            &lt;artifactId&gt;mongodb-driver-sync&lt;/artifactId&gt;
            &lt;version&gt;4.8.1&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
            &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
            &lt;version&gt;2.14.0&lt;/version&gt;
        &lt;/dependency&gt;
英文:

Below is some working code where you can see that I write to the DB and read back data.

Several things are not clear in your question which may either explain why your attempt did not work, or I have misunderstood your requirement.

Person class

Person is a POJO - for this you probably don't want to use a straight class. In the way created it is awkward to construct the Person - I had to create a little helper method as there is no constructor in your class:

private static Person makePerson(String id, String type, int age) {
    Person p = new Person();
    p.setPersonID(id);
    p.setType(type);
    p.setAge(age);
    return p;
}

Whereas, if you make a few small alterations and use a data class then this implicitly gives you a constructor, toString(), hashCode():

@JsonInclude(JsonInclude.Include.NON_NULL)
data class Person (     //&lt;&lt; round brackets

    @JsonProperty(&quot;_id&quot;)
    var personID: String? = null,  //&lt;&lt; comma

    @JsonProperty(&quot;name&quot;)
    var type: String? = null,

    @JsonProperty(&quot;age&quot;)
    var age: Int? = null,

)

Codec setup

I don't think you have your Codecs setup in the right way. (If a Codec is missing you will get a startup error.). Observe my working code.

What is your intended output?

You say it is "not as expected", is it that it is missing the age and name/type field? The field name is "ID" too, what do you want? personID, _id or ID ?

How is your output implemented now?

How are you extracting and displaying the data in JSON - you don't say but given the annotations you use (@JsonProperty), you must be using Jackson, I have included that in my code sample. The Quick Start Guide you refer to talks about @BsonProperty - this is for a different purpose - for how to name the fields in the database, where as @JsonProperty is for naming in JSON.

Specimen code

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;

import java.util.ArrayList;
import java.util.List;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;

public class Test {

    public static void main(String[] args) {
        ConnectionString connectionString = new ConnectionString(&quot;mongodb://127.0.0.1:27017&quot;);
        CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
        MongoClientSettings clientSettings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .codecRegistry(codecRegistry)
                .build();
        try (MongoClient mongoClient = MongoClients.create(clientSettings)) {
            MongoDatabase database = mongoClient.getDatabase(&quot;person&quot;);
            MongoCollection&lt;Person&gt; collection = database.getCollection(&quot;personCollection&quot;, Person.class);

            List&lt;Person&gt; persons = new ArrayList&lt;&gt;();
            persons.add(makePerson(&quot;personId1&quot;, &quot;Lesley&quot;, 10));
            persons.add(makePerson(&quot;personId2&quot;, &quot;Bob&quot;, 20));
            persons.add(makePerson(&quot;personId3&quot;, &quot;Jane&quot;, 30));

            collection.insertMany(persons);

            List&lt;Person&gt; persons2 = collection.find().into(new ArrayList&lt;Person&gt;());
            ObjectMapper mapper = new ObjectMapper();
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(persons2));

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    private static Person makePerson(String id, String type, int age) {
        Person p = new Person();
        p.setPersonID(id);
        p.setType(type);
        p.setAge(age);
        return p;
    }
}

And the output is:

[ {
  &quot;_id&quot; : &quot;personId1&quot;,
  &quot;name&quot; : &quot;Lesley&quot;,
  &quot;age&quot; : 10
}, {
  &quot;_id&quot; : &quot;personId2&quot;,
  &quot;name&quot; : &quot;Bob&quot;,
  &quot;age&quot; : 20
}, {
  &quot;_id&quot; : &quot;personId3&quot;,
  &quot;name&quot; : &quot;Jane&quot;,
  &quot;age&quot; : 30
} ]

And the dependencies I used:

        &lt;dependency&gt;
            &lt;groupId&gt;org.mongodb&lt;/groupId&gt;
            &lt;artifactId&gt;mongodb-driver-sync&lt;/artifactId&gt;
            &lt;version&gt;4.8.1&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
            &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
            &lt;version&gt;2.14.0&lt;/version&gt;
        &lt;/dependency&gt;

huangapple
  • 本文由 发表于 2023年6月8日 18:44:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76431033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定