2017-11-05 8 views
2

Ich habe einen Code, der Daten in einem bestimmten Format von MongoDB liest. Ich muss es testen.MongoDB: versucht, Long aus JSON zu lesen verursacht java.lang.Integer kann nicht in java.lang.Long umgesetzt werden

Um zu tun, erstelle ich eine JSON mit den Daten möchte ich Test:

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

Dies ist das Objekt, das soll erstellt werden:

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

Ich habe einen Code dass liest eine JSON-Datei und erstellt ein Mongo Dokument und schreibt an eine 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); 

Sobald die Daten geschrieben wird, gibt es ein Code, der die Daten von MongoDB und füllt ihn in eine MyObject Instanz zu lesen versucht:

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

, die auf einer Fehlermeldung fehlschlägt:

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

Aufgrund der Linie serial = doc.getLong(DBConstants.SERIAL);. Es bekommt im Grunde die Nummer von meinem JSON als "Integer" und kann es daher nicht so lange lesen.

Ich habe die folgende Zeile versucht, und es funktioniert:

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

Aber ist es die beste Lösung, denn hier? Will .toString() immer bekomme ich die String-Darstellung einer Zahl? Gibt es eine Möglichkeit, eine Nummer in JSON zu behalten, die dazu führen würde, dass sie als Long gelesen wird?

Update:

@glytching gab eine ausgezeichnete Antwort!

Ich entdeckte auch einen anderen Weg, anscheinend, wenn Sie das numerische Element von JSON in NumberLong wickeln wird es als Long geparst werden, wenn aus Mongo Dokument übersetzt.

Also den alten Code, konnte ich es wie so durch die Änderung meiner JSON funktioniert:

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

Antwort

2

Der Mongo Java-Treiber hat festgestellt, dass der Wert der serial kann ‚fit‘ in einem INT32 so es behandelt es so. Wenn Sie doc.getLong() aufrufen, bitten Sie den Treiber, seine Ganzzahl auf ein Long zu setzen, daher die Klassenausnahme. Wenn beispielsweise der Wert serial2147483648 ist (d. H. Der maximale ganzzahlige Wert + 1), dann würde der Mongo-Java-Treiber dies als INT64 ansehen, und Sie könnten dann sicher doc.getLong() aufrufen.

Also, da (a) Sie dieses Attribut als Long in Ihrem Klassenmodell modellierten und (b) nicht jeder beharrte Wert dieses Attributs erfordert Speicher als INT64 ... Sie müssen seinen persistenten Typen empfindlich sein wenn Sie es in ein Long konvertieren.

Wie? Nun, solange das Attribut serial als irgendeine Art von Nummer beibehalten wird (z. B. INT32, INT64), dann ...

doc.get(DBConstants.SERIAL) 

... wird immer ein Objekt zurückgeben, das einige Unterklassen von java.lang.Number ist und daher Number Gießen und mit longValue() arbeiten.

Zum Beispiel:

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