java往MongoDB插入數據時候,會多一個nameValuePairs節點,而且在也無法正常查詢有該節點的數據,查詢時的error:
java.lang.UnsupportedOperationException: No accessor to set property private final java.util.Map org.springframework.boot.configurationprocessor.json.JSONObject.nameValuePairs!
我們看一下JSONObject這個類,它是map的數據結構,每次在實例化一個JSONObject的時候,就會生成一個LinkedHashMap類型的nameValuePairs。所以這種數據格式不滿足我們的業務需求。
這裏的處理方式就是用Mongo獨有的BsonDocument代替JSONObject插入到MongoDB中,
注意一下,其實BsonDocument也是key、value的形式,在put值的時候,要注意一下,java中的基本數據類型要替換成Bson類型,以滿足需要。例如int類型對應BsonInt32,String類型對應BsonString。
BsonDocument bsonDocument = new BsonDocument();
bsonDocument.put("TEST_ID",new BsonInt32(2));
bsonDocument.put("IS_FLAG", new BsonBoolean(true));
bsonDocument.put("TYPE", new BsonString("TEST"));
這裏再往Mongo查詢該數據的時候,還是會出問題的,是沒有辦法將String轉爲BsonValue,具體的Error
ERROR (DirectJDKLog.java:175)- Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.bson.BsonValue]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.bson.BsonValue]
Mongo是可以自定義轉化器的,這裏我沒有往轉換器這一塊去研究,而是通過改進Mongo的查詢方法來進行查詢。不過修改後的方法又需要重新與Mongo建立連接,性能上的問題還需要繼續深究一下。
修改前的寫法:
@Override
public MessageFlowJson getMessageFlowJsonById(ObjectId id) {
log.info("getMessageFlowJsonById() invoked, id:{}", id);
Query query = new Query(Criteria.where("id").is(id));
return mongoTemplate.findOne(query, MessageFlowJson.class);
}
修改後的寫法:
@Override
public MessageFlowJson getMessageFlowJsonById(ObjectId id) {
log.info("getMessageFlowJsonById() invoked, id:{}", id);
MongoClient mongoClient = MongoClients.create("mongodb://XXX");
CodecRegistry pojoCodecRegistry = org.bson.codecs.configuration.CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
org.bson.codecs.configuration.CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build()));
MongoDatabase database = mongoClient.getDatabase("Database").withCodecRegistry(pojoCodecRegistry);
MongoCollection<MessageFlowJson> collection = database.getCollection("MessageFlow", MessageFlowJson.class);
Document query = new Document("_id", id);
List<MessageFlowJson> results = new ArrayList<>();
collection.find(query).into(results);
if(results.size() ==0){
return null;
}
return results.get(0);
}