2012-09-06 29 views
5

Tôi có một trường trong tài liệu MongoDB lưu trữ một số lượng lớn tùy ý. Khi tôi lấy nó như là một (trình điều khiển Java cho MongoDB) DBObject, đôi khi tôi chạy vào một ClassCastException:MongoDB/Java: Gõ an toàn trong DBObjects

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

Nếu giá trị được lưu trữ trong numericVal là, nói, 1234567890, dàn diễn viên Long thành công. Nếu nó là, giả sử, 12345, DBObject.get() trả về một đôi, và diễn viên thất bại.

Làm cách nào để đảm bảo an toàn loại khi deserializing MongoDB DBObjects?

+0

bạn có tích cực là giá trị '12345' không? Có cách nào đó với mongo để xem xét giá trị thô - liệu nó có biểu diễn JSON không? –

+0

tôi đã nhập nó qua vỏ là 12345, nhưng khi tôi in nó trong vỏ nó xuất hiện là 12345.0. rõ ràng đó là một vấn đề về phía trình phân tích cú pháp (trình điều khiển java), nhưng tôi không biết nó đã xảy ra như thế nào trên phía Mongo ngay từ đầu. mà nói, tôi muốn biết làm thế nào để duy trì an toàn loại nói chung với trình điều khiển java. – ericsoco

Trả lời

5

Tôi nghĩ bạn có thể tránh ClassCastException bằng cách sử dụng loại getLong an toàn (String key) thay vì cast (Long) và hy vọng autoboxing làm điều đúng để đưa bạn xuống ít 'l'.

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

Tôi cũng là hoài nghi về 12345 trở thành đôi. Có cái gì đó khác đang diễn ra ở đây.

+0

không thấy getters loại an toàn trong BasicBSONObject vì tôi đang xem tài liệu cho giao diện BSONObject thay thế. cảm ơn vì đã chỉ ra điều đó. (đang tìm kiếm một ví dụ cho thấy làm thế nào để deserialize đối tượng mongo với trình điều khiển java nhưng không thể tìm thấy bất cứ điều gì!) Tuy nhiên, có, chắc chắn có cái gì khác đang xảy ra ở đây ... nhập 1234567890 cho 'numericVal' (trong shell) xuất hiện dưới dạng 1.234567890E9 trong trình gỡ lỗi nhật thực, cũng xuất hiện dưới dạng Double. sẽ báo cáo lại ngay ... – ericsoco

+0

'getLong()' đã hoạt động rất tốt. dunno những gì đã được với các loại chuyển đổi giữa vỏ và trình điều khiển, nhưng bây giờ tôi không quan tâm;) – ericsoco

4

Nói chung tôi nhận thấy rằng các giá trị số được chèn vào như đôi sử dụng vỏ (hoặc đôi khi sử dụng các ngôn ngữ khác)

Vì vậy, ví dụ:

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

chèn một giá trị kép (30.000.000,0) nhưng

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

chèn giá trị chính xác vào bộ sưu tập

Vì vậy, nếu bạn nghi ngờ tránh loại đúc này hoặc bạn có thể làm điều gì đó như:

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