2

I use org.springframework.data.mongodb.core.MongoTemplate to save data to MongoDB. My sample data is following bean:

public class SampleBean{
    private Date date;
    private List<Date>  datesList;
    private TreeMap<Date, Integer> datesMap;
    // setters and getters
}

I am calling following instructions.

SampleBean bean = new SampleBean();
MongoTemplate mongo = new MongoTemplate();

List<Date> dateList = new ArrayList<Date>();
dateList.add(new Date());
TreeMap<Date,Integer> dateMap = new TreeMap<Date, Integer>();
dateMap.put(new Date(), new Integer(1));

bean.setDate(new Date());
bean.setDateList(dateList);
bean.setDateMap(dateMap);

mongo.save(bean, "SampleBean");

And this is what i get in mongo:

{
    "_id" : ObjectId("53d028eeb71a1523582b1b1c"),
    "_class" : "example.SampleBean",
    "date" : ISODate("2014-07-23T21:28:14.869Z"),
    "datesList" : [ 
        ISODate("2014-07-23T21:28:14.876Z")
    ],
    "datesMap" : {
        "Wed Jul 23 23:28:14 CEST 2014" : 1
    }
}

Because of way it's stored I am not able to load bean from MongoDB I get

 Handler execution resulted in exception - forwarding to resolved error view
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.util.Date for value 'Wed Jul 23 23:28:14 CEST 2014'; nested exception is java.lang.IllegalArgumentException

Why Date from TreeMap is not stored as ISODate?

Am I doing anything wrong?

1 Answer 1

1

What you are doing here is breaking a cardinal rule of general "Hash" structures that exists everywhere else outside of Java. The basic concept here is that the "keys" of a Hash or Map can only be a string and not a specific type.

MongoDB uses BSON which is the "binary" and "typed" form derived from the JSON spec. Conforming to the general JSON semantics, the "keys" of a BSON document must be strings and not of any other specific type.

This is at least how MongoDB enforces it. So the general rule of thumb here is don't put other types in the key of a Map other than string.

This really isn't good practice anyway, as "data" as a key is generally bad news. You are better off presenting as an array, like so:

"dates": [
    { "date": ISODate("2014-07-23T21:28:14.876Z"), "count": 1 }
]

These are easier for MongoDB to process in queries without using client side processing or JavaScript as in MapReduce. For general MongoDB queries, Map type structures need to be represented with absolute paths to their keys.

So 1. Don't use other types for keys than strings, they will be stringified anyway. 2. Don't use data as keys, use arrays instead.

Sign up to request clarification or add additional context in comments.

1 Comment

"exists everywhere else outside of Java" is a very MongoDB-centric way of looking at the world and definitely ignoring the reality of hash functions available in most general-purpose programming languages

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.