代码之家  ›  专栏  ›  技术社区  ›  Naveen Santhanavel

使用Java驱动程序将带有JsonNode字段的POJO插入MongoDB

  •  1
  • Naveen Santhanavel  · 技术社区  · 7 年前

    Im使用Mongo Java驱动程序3.7

    这是我的POJO(有getter和setter)-

    public class Sample{
        public int field1;
        public JsonNode field2;
    }
    

    我使用下面的代码将示例对象插入MongoDB。

    MongoCollection<Sample> myCollection = database.getCollection("myCollection",Sample.class);
    ObjectMapper mapper = new ObjectMapper();
        Sample obj = new Sample();
        obj.setField1(1);
        String sampleJSON = "{ \"key\": \"value\" }";
        obj.setField2(mapper.readTree(sample));
    
    myCollection.insertOne(obj);
    

    查看输出:( JsonNode字段为空 )

    {
        "_id" : ObjectId("5afbff8a8f621e1e328a8c4e"),
        "field1" : 1
        "field2" : [
                     [ ]
                   ],
    }
    

    注: 在调试模式下,很明显JsonNode是用正确的数据创建的。但insert行为不端。 我想我错过了什么。感谢任何潜在客户。

    更新时间: 我尝试为JsonNode类编写自定义编解码器,但mongo从未使用过它。这是我的编解码器代码-

    @Slf4j
    public class JsonNodeCodec implements CollectibleCodec<JsonNode> {
        @Inject
        private ObjectMapper objectMapper;
    
        @Override
        public JsonNode generateIdIfAbsentFromDocument(JsonNode jsonNode) {
            return null;
        }
    
        @Override
        public boolean documentHasId(JsonNode jsonNode) {
            return false;
        }
    
        @Override
        public BsonValue getDocumentId(JsonNode jsonNode) {
            return null;
        }
    
        @Override
        public JsonNode decode(BsonReader reader, DecoderContext decoderContext) {
            String task = reader.readString();
            JsonNode node = objectMapper.readTree(task);
            return node;
        }
    
        @Override
        public void encode(BsonWriter writer, JsonNode jsonNode, EncoderContext encoderContext) {
            writer.writeString(jsonNode.toString());
        }
    
        @Override
        public Class<JsonNode> getEncoderClass() {
            return JsonNode.class;
        }
    }
    

    我正在像这样注册编解码器-

    Codec<JsonNode> jsonNodeCodec = new JsonNodeCodec();
    CodecRegistry codecRegistry = CodecRegistries.fromRegistries(com.mongodb.MongoClient.getDefaultCodecRegistry(),
                CodecRegistries.fromCodecs(jsonNodeCodec),
                CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
        );
    

    PS:为自定义POJO注册的其他编解码器工作正常。但该编解码器从未用于对JSON对象进行编码/解码

    2 回复  |  直到 7 年前
        1
  •  5
  •   Rajat Goel    5 年前

    只需添加自定义转换器即可将JsonNode对象转换为org。布森。文件,反之亦然。使用JsonNode字段保持POJO/Document类不变。如果使用弹簧:

    @Bean
    public MongoCustomConversions mongoCustomConversions() {
        List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(JsonNodeToDocumentConverter.INSTANCE);
        converters.add(DocumentToJsonNodeConverter.INSTANCE);
        return new MongoCustomConversions(converters);
    }
    
    @WritingConverter
    enum JsonNodeToDocumentConverter implements Converter<JsonNode, Document> {
        INSTANCE;
    
        public Document convert(JsonNode source) {
            if(source == null)
                return null;
    
            return Document.parse(source.toString());
        }
    }
    
    @ReadingConverter
    enum DocumentToJsonNodeConverter implements Converter<Document, JsonNode> {
        INSTANCE;
    
        public JsonNode convert(Document source) {
            if(source == null)
                return null;
    
            ObjectMapper mapper = new ObjectMapper();
            try {
                return mapper.readTree(source.toJson());
            } catch (IOException e) {
                throw new RuntimeException("Unable to parse DbObject to JsonNode", e);
            }
        }
    }
    
        2
  •  1
  •   Somil Aseeja    6 年前

    我在这里遇到了同样的问题,并使用ObjectMapper解决了这个问题。

    使用如下:

    ObjectMapper mapper =   new ObjectMapper();
    Map inputMap        =   mapper.convertValue(jsonNode, Map.class);