【问题标题】:Convert MongoDB entry to Java Class Model Object将 MongoDB 条目转换为 Java 类模型对象
【发布时间】:2018-03-23 13:08:44
【问题描述】:

我将一个名为 Device 的自定义 java 对象存储到一个 mongo 集合中。这工作正常。但是当我收到数据库条目时,所有内部类对象都分配有 null 而不是数据库值。

这是一个设备:

public class Device {

    public String id;

    public String serialNumber;

    public String name;

    public int status;

    public String errorReport;

    public List<Sensor> sensors=new ArrayList<>();

    public List<Action> actions=new ArrayList<>();

    public List<String> filterTags= new ArrayList<>();

    public List protocols;
}

这是数据库中的一个示例条目,您可以看到这些值保存得很好:

    {
        "_id": "7_openHabsamsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda",
        "actions": [
            {
                "_id": "samsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda:volume",
                "deviceId": "7_openHabsamsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda",
                "errorReport": "Value wurde nicht initialisiert",
                "name": "Lautst�rke",
                "state": 0,
                "value": 0,
                "valueOption": {
                    "maximum": 0,
                    "minimum": 0,
                    "percentage": true
                },
                "valueable": true
            }
    ],
    "filterTags": [],
        "name": "[TV] Chine ",
        "sensors": [
            {
                "_id": "samsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda:sourceId",
                "name": "Source ID"
            },
            {
                "_id": "samsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda:programTitle",
                "name": "Titel"
            },
            {
                "_id": "samsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda:channelName",
                "name": "Kanal"
            }
        ],
        "status": 0
    }

这就是我再次从数据库中接收它时的样子:

{
        "id": "7_openHabsamsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda",
        "serialNumber": null,
        "name": "[TV] Chine ",
        "status": 0,
        "errorReport": null,
        "sensors": [
            {
                "id": null,
                "name": null,
                "errorReport": null
            },
            {
                "id": null,
                "name": null,
                "errorReport": null
            },
            {
                "id": null,
                "name": null,
                "errorReport": null
            }
        ],
        "actions": [
            {
                "id": null,
                "name": null,
                "deviceId": null,
                "state": 0,
                "states": null,
                "valueOption": null,
                "value": 0,
                "errorReport": "Value wurde nicht initialisiert",
                "valueable": false
            }
],
        "filterTags": [],
        "protocols": null
    }

因此,当我从我的数据库集合中提取条目时,它会将 SensorAction 的值设置为 null。这是我接收设备的 Java 代码:

MongoClientURI connectionString = new MongoClientURI(dummy);
MongoClient mongoClient = new MongoClient(connectionString);
CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoCollection<Device> devices = database.withCodecRegistry(pojoCodecRegistry).getCollection("devices", Device.class);

Device device = devices.find().first();

我正在使用标准的 MongoDB Java 驱动程序。 谁能告诉我我在这里缺少什么?提前致谢。

【问题讨论】:

  • 为什么不将Morphia ORM 像 Hibernate 用于关系 SQL 数据库。
  • 因为我认为轻量级标准库就足够了。那么没有其他库就没有办法了吗?
  • 他的 filterTags 列表呢,是否填写正确?另外,能否提供一份 mongodb 文档供我们复现?
  • @GeorgMuehlenberg 是的,过滤器标签列表已正确填写。

标签: java mongodb pojo


【解决方案1】:

TL;DR:您需要每个默认配置的 setter 和 getter。

我编写了这个单元测试来重现错误,但它不会重现,除非我使用 Action 和 Sensor 类。我正在使用 Mongodb 3.4 和 Java 驱动程序 3.6。

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.junit.Test;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertNotNull;

public class MongoDeser {

    @Test
    public void testDeser() {
        MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017");
        MongoClient mongoClient = new MongoClient(connectionString);
        MongoDatabase database = mongoClient.getDatabase("sotest");
        PojoCodecProvider codecProvider = PojoCodecProvider.builder()
                .automatic(true)
                .build();

        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(), fromProviders(codecProvider));

        MongoCollection<Device> devices = database.withCodecRegistry(pojoCodecRegistry).getCollection("device", Device.class);

        Device device = devices.find().first();

        assertNotNull(device.getActions());
        assertThat(device.getActions().size(), is(1));
        assertThat(device.getActions().get(0).getDeviceId(), is("7_openHabsamsungtv:tv:cbaf7d7d_4e10_41e6_9c1d_864988057bda"));
        assertThat(device.getStatus(), is(0));
        assertThat(device.getName(), is("[TV] Chine "));
    }

}

您的 POJO 中是否缺少 getter 和/或 setter?

Mongodb Java 驱动程序uses reflection 用于从 BSON 映射 POJO。每个默认配置都需要这些 Getter 和 Setter。如果你没有它们,它可能会出现异常行为。在我的测试中,有时它找不到编解码器并引发异常,有时字段就像您的情况一样被清空。我的建议是改用注释并为 Java 驱动程序提供一个约定。

传感器类

import java.io.Serializable;

public class Sensor implements Serializable
{

    private String id;
    private String name;
    private final static long serialVersionUID = 8244091126694748358L;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

}

动作类

import java.io.Serializable;

public class Action implements Serializable
{

    private String id;
    private String deviceId;
    private String errorReport;
    private String name;
    private long state;
    private long value;
    private ValueOption valueOption;
    private boolean valueable;
    private final static long serialVersionUID = 3493217442158516855L;

    public String getId() {
        return id;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public String getErrorReport() {
        return errorReport;
    }

    public String getName() {
        return name;
    }

    public long getState() {
        return state;
    }

    public long getValue() {
        return value;
    }

    public ValueOption getValueOption() {
        return valueOption;
    }

    public boolean isValueable() {
        return valueable;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

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

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    public void setErrorReport(String errorReport) {
        this.errorReport = errorReport;
    }

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

    public void setState(long state) {
        this.state = state;
    }

    public void setValue(long value) {
        this.value = value;
    }

    public void setValueOption(ValueOption valueOption) {
        this.valueOption = valueOption;
    }

    public void setValueable(boolean valueable) {
        this.valueable = valueable;
    }
}

【讨论】:

  • 你确定它是正确的,因为我在你的代码中看不到任何 Sensor 或 Action 类。
  • 我将它们添加到我的答案中。
  • 你从哪里得到serialVersionUID?
  • 成功了,我没有属性设置器
  • 对于serialVersionUID,请参见此处:stackoverflow.com/questions/285793/…
【解决方案2】:
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromProviders(new pojoCodecRegistryCodecProvider()),
CodecRegistries.fromProviders(new ActionCodecProvider()),
CodecRegistries.fromProviders(new SensorCodecProvider()));

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 1970-01-01
  • 2014-08-15
  • 2016-10-21
  • 1970-01-01
相关资源
最近更新 更多