2012-09-06 16 views
5

Tengo un campo en un documento MongoDB que almacena un número arbitrariamente grande. Cuando puedo recuperarlo como un (controlador Java para MongoDB) dbobject, a veces me encuentro con un ClassCastException:MongoDB/Java: escriba safety en DBObjects

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

Si el valor almacenado en numericVal es, por ejemplo, 1234567890, el elenco de largo tiene éxito. Si es, digamos, 12345, DBObject.get() devuelve un doble y el lanzamiento falla.

¿Cómo puedo garantizar la seguridad del tipo cuando deserializo MongoDB DBObjects?

+0

son positivos que el valor es '12345'? ¿Hay alguna forma con mongo de mirar el valor bruto? ¿Tiene una representación JSON? –

+0

lo ingresé a través del shell como 12345, pero cuando lo imprimo en el shell aparece como 12345.0. obviamente ese es un problema en el lado del analizador (controlador de Java), pero no sé cómo sucedió en el lado de Mongo en primer lugar. Dicho esto, me gustaría saber cómo mantener la seguridad del tipo en general con el controlador de Java. – ericsoco

Respuesta

5

Creo que puede evitar ClassCastException utilizando el tipo getLong seguro (clave de cadena) en lugar de lanzar (Long) y esperar que el autoboxing haga lo correcto para reducirlo a 'l' long.

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"); 

yo también soy escéptico de la 12345 convertirse en doble. Hay algo más pasando aquí.

+0

no vio los captadores de tipo seguro en BasicBSONObject porque en su lugar estaba buscando los documentos para la interfaz BSONObject. gracias por señalar eso. (estaba buscando un ejemplo que muestre cómo deserializar los objetos de mongo con el controlador de Java pero no pudo encontrar nada). Sin embargo, sí, definitivamente hay algo más sucediendo aquí ... ingresando 1234567890 para 'numericVal' (en shell) aparece como 1.234567890E9 en el eclipse depurador, que también aparece como un doble. informará en breve ... – ericsoco

+0

'getLong()' funcionó muy bien. no sé qué pasó con la conversión de tipo entre el shell y el controlador, pero ahora no me importa;) – ericsoco

4

En general he notado que los valores numéricos se insertan como doble usando la cáscara (o, a veces el uso de otros idiomas)

Así, por ejemplo:

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

inserta un valor doble (30000000.0) pero

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

inserta el valor correcto en la colección

Así que si usted está en duda evitar este tipo de fundición o puede hacer algo como:

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