@ -81,6 +81,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@@ -81,6 +81,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
protected ApplicationContext applicationContext ;
protected boolean useFieldAccessOnly = true ;
protected MongoTypeMapper typeMapper ;
protected String mapKeyDotReplacement = null ;
private SpELContext spELContext ;
@ -120,6 +121,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@@ -120,6 +121,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
mappingContext ) : typeMapper ;
}
/ * *
* Configure the characters dots potentially contained in a { @link Map } shall be replaced with . By default we don ' t do
* any translation but rather reject a { @link Map } with keys containing dots causing the conversion for the entire
* object to fail . If further customization of the translation is needed , have a look at
* { @link # potentiallyEscapeMapKey ( String ) } as well as { @link # potentiallyUnescapeMapKey ( String ) } .
*
* @param mapKeyDotReplacement the mapKeyDotReplacement to set
* /
public void setMapKeyDotReplacement ( String mapKeyDotReplacement ) {
this . mapKeyDotReplacement = mapKeyDotReplacement ;
}
/ *
* ( non - Javadoc )
* @see org . springframework . data . convert . EntityConverter # getMappingContext ( )
@ -507,7 +520,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@@ -507,7 +520,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if ( conversions . isSimpleType ( key . getClass ( ) ) ) {
// Don't use conversion service here as removal of ObjectToString converter results in some primitive types not
// being convertable
String simpleKey = key . toString ( ) ;
String simpleKey = potentiallyEscapeMapKey ( key . toString ( ) ) ;
if ( val = = null | | conversions . isSimpleType ( val . getClass ( ) ) ) {
writeSimpleInternal ( val , dbo , simpleKey ) ;
} else if ( val instanceof Collection | | val . getClass ( ) . isArray ( ) ) {
@ -528,6 +541,39 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@@ -528,6 +541,39 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return dbo ;
}
/ * *
* Potentially replaces dots in the given map key with the configured map key replacement if configured or aborts
* conversion if none is configured .
*
* @see # setMapKeyDotReplacement ( String )
* @param source
* @return
* /
protected String potentiallyEscapeMapKey ( String source ) {
if ( ! source . contains ( "." ) ) {
return source ;
}
if ( mapKeyDotReplacement = = null ) {
throw new MappingException ( String . format ( "Map key %s contains dots but no replacement was configured! Make "
+ "sure map keys don't contain dots in the first place or configure an appropriate replacement!" , source ) ) ;
}
return source . replaceAll ( "\\." , mapKeyDotReplacement ) ;
}
/ * *
* Translates the map key replacements in the given key just read with a dot in case a map key replacement has been
* configured .
*
* @param source
* @return
* /
protected String potentiallyUnescapeMapKey ( String source ) {
return mapKeyDotReplacement = = null ? source : source . replaceAll ( mapKeyDotReplacement , "\\." ) ;
}
/ * *
* Adds custom type information to the given { @link DBObject } if necessary . That is if the value is not the same as
* the one given . This is usually the case if you store a subtype of the actual declared type of the property .
@ -692,12 +738,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@@ -692,12 +738,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
continue ;
}
Object key = entry . getKey ( ) ;
Object key = potentiallyUnescapeMapKey ( entry . getKey ( ) ) ;
TypeInformation < ? > keyTypeInformation = type . getComponentType ( ) ;
if ( keyTypeInformation ! = null ) {
Class < ? > keyType = keyTypeInformation . getType ( ) ;
key = conversionService . convert ( entry . getKey ( ) , keyType ) ;
key = conversionService . convert ( key , keyType ) ;
}
Object value = entry . getValue ( ) ;