微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MongoDB:尝试从JSON读取Long导致java.lang.Integer无法转换为java.lang.Long

我有一个代码,可以从MongoDB中读取特定格式的数据.我需要测试一下.

为此,我使用要测试的数据创建了一个JSON

{
  "id": ObjectId("57552e32e4b0839ede67e0af"),
  "serial" : 574000690,
  "startDate" : ISODate("2016-08-22T23:01:56.000Z"),
  "endDate" : ISODate("2016-10-22T22:01:56.000Z"),
  "reason": ""
}

这是应该创建的对象:

public static class MyObject implements Serializable{
    private String id;
    private long serial;
    private Date startDate;
    private Date endDate;
    private String reason;
}

我有一个读取JSON文件并创建Mongo文档并写入DB的代码

List<Document> docs = dirAsDbObjects(dir + File.separator + 
subDir.getName()).collect(Collectors.toList());

docs.forEach(docManipulator);
docs.forEach(doc -> doc.putIfAbsent("_id", new ObjectId()));

ret.addAll(docs);

MongoDatabase db = mongoClient.getDatabase(dbname);
MongoCollection<Document> coll = db.getCollection(subDir.getName());

List<InsertOneModel<Document>> inserts = docs.stream().map(InsertOneModel::new).collect(Collectors.toList());
coll.bulkWrite(inserts);

写入数据后,将有一个代码尝试从MongoDB中读取数据并将其填充到MyObject实例中:

    public MyObject(Document doc) {
        id = doc.getobjectId(DBConstants.ID).toString();
        serial = doc.getLong(DBConstants.SERIAL);
        startDate = doc.getDate("startDate");
        reason = doc.getString("source");
    }

失败并显示错误消息:

java.lang.classCastException: java.lang.Integer cannot be cast to java.lang.Long

由于该行serial = doc.getLong(DBConstants.SERIAL);.它基本上从我的JSON中获取为“ Integer”的数字,因此无法长时间读取.

我已经尝试了以下行,并且行得通:

Long.parseLong(doc.get(DBConstants.SERIAL).toString())

但这是最好的解决方案吗? .toString()总是让我得到数字的字符串表示形式吗?有没有一种方法可以将数字保留在JSON中,从而导致将其读取为Long?

更新:

@glytching提供了一个很好的答案!

我还发现了另一种方法,显然,如果将Number的JSON数字元素包装在NumberLong中,则从Mongo文档进行翻译时,它将解析为Long.

因此,使用旧代码,我可以通过更改JSON使其生效:

{
  "id": ObjectId("57552e32e4b0839ede67e0af"),
  "serial" : NumberLong(574000690),
  "startDate" : ISODate("2016-08-22T23:01:56.000Z"),
  "endDate" : ISODate("2016-10-22T22:01:56.000Z"),
  "reason": ""
}

解决方法:

Mongo Java驱动程序已确定serial的值可以“适合” INT32,因此将其视为此类.调用doc.getLong()时,您要求驱动程序将其Integer强制转换为Long,因此是类强制转换异常.例如,如果serial的值为2147483648(即最大整数值1),则Mongo Java驱动程序会将其视为INT64,然后可以安全地调用doc.getLong().

因此,由于(a)在类模型中将此属性建模为Long,并且(b)并非该属性的每个持久值都需要存储为INT64 … …在将其转换为INT64时,必须对其持久性类型敏感长.

怎么样?好吧,只要将串行属性保留为某种数字(例如INT32,INT64),那么此调用就可以了…

doc.get(DBConstants.SERIAL)

…将始终返回一个对象,该对象是java.lang.Number的某些子类,因此强制转换为Number并使用longValue()即可.

例如:

serial = ((Number) doc.get(DBConstants.SERIAL)).longValue()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐