2012-09-06 7 views
5

Ich habe ein Feld in einem MongoDB-Dokument, das eine beliebig große Zahl speichert. Wenn ich es als DBObject (Java-Treiber für MongoDB) abrufen, habe ich manchmal in eine Classcast laufen:MongoDB/Java: Geben Sie Sicherheit in DBObjects ein

DBObject obj = collection.findOne(); 
long val = (Long)(o.get("numericVal")); 

Wenn der in numericVal gespeicherten Wert ist, sagen wir, 1234567890, gelingt es dem Guss auf Long. Wenn es beispielsweise 12345 ist, gibt DBObject.get() ein Double zurück, und die Umwandlung schlägt fehl.

Wie kann ich die Typensicherheit beim Deserialisieren von MongoDB DBObjects sicherstellen?

+0

sind Sie positive der Wert '12345'? Gibt es einen Weg mit Mongo, um den Rohwert zu betrachten - hat er eine JSON-Repräsentation? –

+0

Ich habe es über die Shell als 12345 eingegeben, aber wenn ich es in der Shell drucke, erscheint es als 12345.0. offensichtlich ist das ein Problem auf der Seite des Parsers (Java-Treiber), aber ich weiß nicht, wie es auf der Mongo-Seite überhaupt passiert ist. das heißt, ich würde gerne wissen, wie typsicherheit im allgemeinen mit dem java-treiber zu erhalten. – ericsoco

Antwort

5

Ich denke, Sie können die ClassCastException vermeiden, indem Sie den Typ sicher getLong (String-Schlüssel) statt Cast (Long) und hoffen, dass Autoboxing das richtige tut, um Sie zu wenig 'l' lang zu bekommen.

http://api.mongodb.org/java/2.8.0/org/bson/BasicBSONObject.html#getLong(java.lang.String)

DBObject obj = collection.findOne(); 
long val = o.getLong("numericVal"); 

Ich bin zu skeptisch des 12345 immer doppelt. Hier läuft noch etwas anderes.

+0

konnte die typsicheren Getters in BasicBSONObject nicht sehen, da ich stattdessen die Dokumentation für die Schnittstelle BSONObject betrachtete. Danke, dass du das gezeigt hast. (suchte nach einem Beispiel, das zeigen sollte, wie man Mongo - Objekte mit dem Java - Treiber deserialisiert, aber nichts finden konnte!), aber es gibt definitiv etwas anderes hier ... 1234567890 für 'numericVal' (in der Shell) erscheint als 1.234567890E9 im Eclipse Debugger, der auch als Double herauskommt. werde kurz berichten ... – ericsoco

+0

'getLong()' hat super funktioniert. weiß nicht was mit der typenumwandlung zwischen der shell und dem treiber passiert ist, aber jetzt ist mir egal;) – ericsoco

4

Generell bemerkte ich, dass numerische Werte als doppelt eingefügt werden mit der Schale (oder manchmal auch andere Sprachen verwendet wird)

So zum Beispiel:

db.dummycollection.update({"mykey" : 100}, { $set : { "millisecage" : 30000000 }}) 

fügt einen Doppelwert (30.000.000,0) aber

db.dummycollection.update({"mykey" : 100}, { $set : { "millisecage" : NumberLong(30000000) }}) 

fügt den korrekten Wert in der Sammlung

Also, wenn Sie im Zweifel sind, diese Art von Gießen vermeiden oder Sie können wie etwas tun:

Long myValue = ((Number) obj.get("yourkey")).longValue(); 
Verwandte Themen