如何使用PojoCodecProvider忽略getter / setter

时间:2018-01-10 22:29:24

标签: java mongodb codec

我正在尝试使用数据传输对象pojo设置MongoCollection来返回/保存,但我无法弄清楚如何配置pojo编解码器以忽略getter / setter。

现在我收到了错误

Caused by: org.bson.codecs.configuration.CodecConfigurationException: Property 'iLink' in BasicRecord, has differing data types: TypeData{type=BasicLink} and TypeData{type=ILink}

我不控制数据传输对象,并且没有“iLink”属性。 (该属性只是“链接”,对象属性名称,已经是“链接”用于系统之间的序列化/反序列化.getILink只是从ILink接口继承的getLink的通用版本)

这是构建pojo编解码器的代码

    // Create a Codec for converting BsonDate to java.time.Instant
    final HashMap<BsonType, Class<?>> replacements = new HashMap<>();
    replacements.put(BsonType.DATE_TIME, Instant.class);
    final BsonTypeClassMap bsonTypeClassMap = new BsonTypeClassMap(replacements);
    final Codec<Document> instantCodec = new DocumentCodec(MongoClient.getDefaultCodecRegistry(), bsonTypeClassMap);

    // Create class Codec
    final CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register(this.type).build();

    // Combine Codecs together into one registry
    final CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(CodecRegistries.fromCodecs(instantCodec),
            CodecRegistries.fromProviders(pojoCodecProvider), MongoClient.getDefaultCodecRegistry());

    final MongoDatabase database = this.client.getDatabase(database_name).withCodecRegistry(pojoCodecRegistry);
    this.collection = database.getCollection(collection_name, classType);

我只需要pojo编解码器在编码/解码时使用类属性字段。我完全可以控制构建编解码器部分,所以如果我需要使用反射来构建一个ClassModel,那很好。

(这是我尝试使用ClassModel构建器,但是 removeProperty似乎没有改变任何东西从构造函数抛出异常,所以我从来没有机会调用removeProperty。 )

    final ClassModelBuilder<T> builder = ClassModel.builder(this.type);
    builder.removeProperty("iLink");
    final CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register(builder.build()).build();

1 个答案:

答案 0 :(得分:1)

PojoCodecProvider目前(从mongo-java-driver版本3.6.2开始)不支持关闭getter / setter属性。

您可以迭代构建器找到的属性,并使用这样的函数删除无效的属性(可以将其包装为convention。请注意,驱动程序3.6.2在发现过程中比版本更好3.5.0)。

private void stripNonProperties(final ClassModelBuilder<T> builder, Class<T> type) {
    // Need intermediary list. Can't remove from list while iterating over it
    final ArrayList<String> names = new ArrayList<>();

    for (final org.bson.codecs.pojo.PropertyModelBuilder<?> property : builder.getPropertyModelBuilders()) {
        final String name = property.getName();
        if (!isField(name, type)) {
            names.add(name);
        }
    }

    for (final String name : names) {
        builder.removeProperty(name);
    }
}

否则,您只需要将相关对象转换为您可以控制的版本。