MongoDBにデータを登録しようとしたところ、 以下のエラーが発生しました。 エラー原因と対処方法を備忘としてメモします。
1.エラー内容
Exception in thread "main" java.lang.IllegalArgumentException: Invalid BSON field name java.runtime.name
at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:494)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:188)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:172)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:172)
at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:99)
at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:43)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBody(BaseWriteCommandMessage.java:112)
at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBody(BaseWriteCommandMessage.java:35)
at com.mongodb.connection.RequestMessage.encode(RequestMessage.java:132)
at com.mongodb.connection.BaseWriteCommandMessage.encode(BaseWriteCommandMessage.java:89)
at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:170)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:73)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:66)
at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
at com.mongodb.connection.DefaultServerConnection.insertCommand(DefaultServerConnection.java:108)
at com.mongodb.operation.MixedBulkWriteOperation$Run$2.executeWriteCommandProtocol(MixedBulkWriteOperation.java:416)
at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:604)
at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:363)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:148)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:141)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:186)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:177)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:141)
at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:72)
at com.mongodb.Mongo.execute(Mongo.java:747)
at com.mongodb.Mongo$2.execute(Mongo.java:730)
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:482)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:277)
2.原因
登録対象データは、javaのSystem.getProperties()の戻りです。
登録データのキー値:Valueとして、以下の形式となるため、エラーとなりました。
{“file.encoding” : “UTF-8”}
※キー値として、”.”を含む値は使えない。
MongoDBの仕様なのか、MongoDriver側の問題なのかはよくわかりません。
3.対処
javaオブジェクトをjacksonを使用してMap化していたので、
SimpleModuleにProperties用のSerializerを追加、
ObjectMapperに登録しました。
“.”がKey値に含まれる場合は、”_”に変換してキー値として使います。
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("jobReportModule", Version.unknownVersion());
module.addSerializer(Properties.class, new JsonSerializer<Properties>() {
@Override
public void serialize(Properties value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
for (String key : value.stringPropertyNames()) {
String convertedKey = key.replace(".", "_");
jgen.writeObjectField(convertedKey, value.get(key));
}
jgen.writeEndObject();
}
});
mapper.registerModule(module);
Map<String, Object> map = mapper.convertValue(report, Map.class);
- 補足
キー値の変換は、PropertyNamingStrategyBaseを使用しても可能ですが、
Nestされたキー値の変換までは行ってくれなかったため、
Serializerを使って、変換処理を実装しました。
以上です。
コメント