Laures
Laures

Reputation: 5479

How to configure handling of Map Properties

I have a User-class that contains a HashMap to map between two custom objects.

Currently whenever i try to save one of the users in mongodb i get:

org.springframework.data.mapping.model.MappingException: Map key net.bigpoint.globalchat.models.keys.ProjectId@0 contains dots but no replacement was configured! Make sure map keys don't contain dots in the first place or configure an appropriate replacement!
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.potentiallyEscapeMapKey(MappingMongoConverter.java:548) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeMapInternal(MappingMongoConverter.java:512) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:385) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:346) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:335) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:173) ~[spring-data-commons-core-1.2.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:335) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:307) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:272) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:73) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:717) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:707) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:703) ~[spring-data-mongodb-1.0.1.RELEASE.jar:na]
at net.bigpoint.globalchat.hazelcast.MongoMapStore.store(MongoMapStore.java:81) [classes/:na]
at net.bigpoint.globalchat.hazelcast.MongoMapStore.store(MongoMapStore.java:1) [classes/:na]
at com.hazelcast.impl.concurrentmap.MapStoreWrapper.store(MapStoreWrapper.java:110) [hazelcast-2.0.2.jar:2.0.2]
at com.hazelcast.impl.ConcurrentMapManager$PutOperationHandler$PutStorer.doMapStoreOperation(ConcurrentMapManager.java:2736) [hazelcast-2.0.2.jar:2.0.2]
at com.hazelcast.impl.ConcurrentMapManager$AbstractMapStoreOperation.run(ConcurrentMapManager.java:3440) [hazelcast-2.0.2.jar:2.0.2]
at com.hazelcast.impl.executor.ParallelExecutorService$ParallelExecutorImpl$ExecutionSegment.run(ParallelExecutorService.java:212) [hazelcast-2.0.2.jar:2.0.2]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_04]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_04]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_04]

It seems to me that spring data tries to serialize the keys by calling toString which would be impossible to deserialize.

I allready have converter for both classes that can turn instances to strings and vice versa, so what is wrong with my setup?

EDIT

For some anoying reason the MappingMongoConverter class doesn't use the converters to turn the keys into something manageable, it simply uses toString to turn the key into a String and write the string into the DBObject.

During deserialization the string (here handled as an object) is converted into the correct key type....

Upvotes: 2

Views: 3282

Answers (1)

Laures
Laures

Reputation: 5479

I'm not sure if the behaviour is intended but as i described in my edit the map key is "serialized" by calling toString (which works for Float,Double and the like) and deserialized by using the configured converters.

so the workaround for me was to call my complexClassToString converter in the classes toString method. This was only possible because i already had this converter because the class in question is used as an ID in my Model.

Upvotes: 1

Related Questions