如何使用 PojoCodecProvider 忽略 getters/setters

How do I ignore getters/setters with PojoCodecProvider

我正在尝试使用数据传输对象 pojo 将 MongoCollection 设置为 return/save,但我不知道如何配置 pojo 编解码器以忽略 getters/setters。

现在我收到错误

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

我不控制数据传输对象,也没有"iLink"属性。 (属性 只是 "link",对象 属性 名称,已经是 "link" 用于系统之间的 serialization/deserialization。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 编解码器在 encoding/decoding 时使用 class 属性 字段。我可以完全控制构建编解码器部分,所以如果我需要使用反射来构建 ClassModel,那很好。

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

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

当前的 PojoCodecProvider(从 mongo-java-驱动程序的 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);
    }
}

否则,您只需将有问题的对象转换为您控制的版本即可。