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);
}