gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:28:50 26 4
gpt4 key购买 nike

我有一段代码可以从 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 文档,然后写入数据库:

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 中获取数字作为“整数”,因此无法长时间读取它。

我试过下面一行,它有效:

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

但这是最好的解决方案吗? .toString() 总能得到数字的字符串表示形式吗?有没有办法在 JSON 中保留一个数字,使其被读取为 Long

更新:

@glytching 给出了很好的答案!

我还发现了另一种方法,显然如果你将 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 ... 在将其转换为 Long 时,您必须对其持久化类型敏感。

如何?好吧,只要 serial 属性作为某种数字(例如 INT32INT64)持久化,那么这个调用 ...

doc.get(DBConstants.SERIAL)

... 将始终返回一个对象,它是 java.lang.Number 的某个子类,因此转换为 Number 并使用 longValue() 将起作用。

例如:

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

关于java - MongoDB:尝试从 JSON 读取 Long 会导致 java.lang.Integer 无法转换为 java.lang.Long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47121602/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com