spring data mongo @Field 失效問題

等燈的鄧發表於2019-01-19

問題

@Field("fs")
public Map<String, Integer> favoriteStickers = new LinkedHashMap<>();

使用MongoTemplate直接為favoriteStickers欄位新增新值key為STICKER@10002,value為1時,@Field配置的別名不會被成功對映。

mongoTemplate.upsert(query(where("uid").is(1), new Update().set("favoriteStickers.STICKER@10002", 1), UserSticker.class);

原因

MongoTemplate會將執行語句中的key(上面的 uidfavoriteStickers.STICKER@10002 )對映成MongoDB中對應的欄位,如果在UserSticker類的定義中有相應的配置則會按配置對映。例如問題欄位使用的@Field就是用來配置別名的。

對於favoriteStickers.12 , 會當作favoriteStickers是個陣列,12為被操作的秩,favoriteStickers屬性在UserSticker中有定義可以成功對映。
對於favoriteStickers.STICKER@10002,會當作是有層級關係。即當作favoriteStickers是一個物件,該物件的定義中有一個STICKER@10002屬性,如果沒有不做對映。favoriteStickers是一個map所以無法對映。

重要原始碼

org.springframework.data.mongodb.core.convert.QueryMapper#getMappedObject(org.bson.conversions.Bson, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity<?>)方法就是直接用來對映物件的,在這個方法中的程式碼Field field = createPropertyField(entity, key, mappingContext);是用來構建欄位的對映關係。

最終會指向org.springframework.data.mongodb.core.convert.QueryMapper.MetadataBackedField#getPath(java.lang.String)這個方法中出問題的就是PropertyPath path = PropertyPath.from(pathExpression.replaceAll("\.\d+", ""), entity.getTypeInformation());這行程式碼又會呼叫org.springframework.data.mapping.PropertyPath#from(java.lang.String, org.springframework.data.util.TypeInformation<?>)

相關文章