java.lang.ClassCastException when mapping to Custom Object

java

Solution

The MongoDB Java driver doesn't support automatically using sub-classes of `BasicDBObject`. That's why you're getting the `ClassCastException`; the objects returned by the driver are `BasicDBObject` instances, not instances of your subclasses.

One option to get this to work would be to replace the casts with constructor calls. For example, in `Test`, replace

CustomChainData ocd = (CustomChainData) testdata.findOne(query);

with

CustomChainData ocd = new CustomChainData(testdata.findOne(query));

and in `CustomChainData`, add

CustomChainData(Map m) {
    super(m);
}

This uses a copy-constructor to allow usage of your `CustomChainData` class with the data loaded from MongoDB. However, you'd need to apply this pattern every time you get back a `BasicDBObject` (for the When object as well, for example).

I prefer the approach of using a library that performs mapping between MongoDB data and Java objects. I've used Morphia in the past and been quite happy with it. Other options are listed in the MongoDB Java Language Center.

Problem

I have a collection as shown below: ``` db.testdata.save( { "Indicator": "One", "secs": [ { "when": "2013-03-16", "num": 16, "choices": [ { "size": "10", "mult": "10" }, { "size": "10", "mult": "10" } ] }, { "when": "2013-03-22", "num": 24, "choices": [ { "size": "100", "mult": "100" }, { "size": "100", "mult": "100" } ] } ] }) ``` I am trying to retrieve it using a Custom Object as shown: ``` public class Test { public static void main(String args[]) throws UnknownHostException { Mongo mongo = new Mongo(); DB db = mongo.getDB("at"); DBCollection testdata = db.getCollection("testdata"); BasicDBObject query = new BasicDBObject(); query.put("Indicator", "One"); CustomChainData ocd = (CustomChainData) testdata.findOne(query); ocd.getWhen().size(); } } ``` ``` import java.util.List; import com.mongodb.BasicDBObject; public class CustomChainData extends BasicDBObject{ public CustomChainData() { super(); } @SuppressWarnings("unchecked") public List<WhenData> getWhen() { return (List<WhenData>) get("secs"); } public void setWhen(List<WhenData> expirationDts) { put("secs", expirationDts); } } ``` ``` import com.mongodb.BasicDBObject; public class WhenData extends BasicDBObject{ public String getSize() { return (String) get("size"); } public void setSize(String size) { put("size", size); } } ``` Unfortunately I kept on getting: Exception in thread "main" java.lang.ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.CustomChainData at Test.main(Test.java:19)

Original source