自定义映射忽略原子足字段

发布于 2025-02-07 19:20:19 字数 1423 浏览 2 评论 0 原文

由于我注意到MAPSTRUCT已更新以与Protobuff及其建筑商进行交互,因此我考虑过迁移我们的服务以完全使用Mapstruct。

但是,我们仍将手动转换转换为Protobuff消息,因为写一个完整的映射是相当笨拙的,考虑到我们具有target_unmapped =错误策略:

compileJava {
    options.compilerArgs += [
            '-Amapstruct.unmappedTargetPolicy=ERROR'
    ]
}

这意味着即使是一个相当简单的映射,即两个具有相同6个相同字段名称的类别( f)看起来像这样:

@Mapper(componentModel = "spring", uses = {...})
public interface ProtoMapperExample {

    @Mapping(target = "aBytes", ignore = true)
    @Mapping(target = "bBytes", ignore = true)
    @Mapping(target = "cBytes", ignore = true)
    @Mapping(target = "dBytes", ignore = true)
    @Mapping(target = "eBytes", ignore = true)
    @Mapping(target = "fBytes", ignore = true)
    @Mapping(target = "mergeFrom", ignore = true)
    @Mapping(target = "clearField", ignore = true)
    @Mapping(target = "clearOneof", ignore = true)
    @Mapping(target = "unknownFields", ignore = true)
    @Mapping(target = "mergeUnknownFields", ignore = true)
    @Mapping(target = "allFields", ignore = true)
    ProtoMessage toMessage(Source s);

}

这是不可接受的。但是关闭错误的选择同样是不可接受的。

我们的解决方案是简单地不使用Mapstruct进行此转换,我完全同意。至少可以说很麻烦。

但是,如果有一种方法可以配置我们的映射器来忽略至少后6个字段(From,Clearfield,Clearoneof,Unknown Fields,Mergeunknownnownfields,Allfields,Allfields),那么人们会假设并希望Mapstruct默认情况下。即使那将是一个进步。

但是我们还需要一种方法来忽略以“*字节”结尾的字段。

有什么方法吗?

Since I've noticed that MapStruct was updated to interact with Protobuff and its builder, I thought about migrating our services to fully use MapStruct.

However we're still writing manual conversions to protobuff messages because it's rather clumsy to write a full mapping, considering we have the target_unmapped = Error policy:

compileJava {
    options.compilerArgs += [
            '-Amapstruct.unmappedTargetPolicy=ERROR'
    ]
}

This means that even a rather simple mapping, of two classes with the same 6 identical field names (a throug f) looks like this:

@Mapper(componentModel = "spring", uses = {...})
public interface ProtoMapperExample {

    @Mapping(target = "aBytes", ignore = true)
    @Mapping(target = "bBytes", ignore = true)
    @Mapping(target = "cBytes", ignore = true)
    @Mapping(target = "dBytes", ignore = true)
    @Mapping(target = "eBytes", ignore = true)
    @Mapping(target = "fBytes", ignore = true)
    @Mapping(target = "mergeFrom", ignore = true)
    @Mapping(target = "clearField", ignore = true)
    @Mapping(target = "clearOneof", ignore = true)
    @Mapping(target = "unknownFields", ignore = true)
    @Mapping(target = "mergeUnknownFields", ignore = true)
    @Mapping(target = "allFields", ignore = true)
    ProtoMessage toMessage(Source s);

}

Which is honestly unacceptable. But the option of turning off the error is just as unacceptable.

Our solution was to simply not use MapStruct for this conversion, and I totally agree. It's cumbersome to say the least.

However if there were a way of configurating our mapper to ignore at least the latter 6 fields (mergeFrom, clearField, clearOneof, unknownFields, mergeUnknownFields, allFields) which one would assume and hope mapstruct did by default. Even that would be an improvement.

But we'd also need a way to ignore fields that end in "*Bytes".

Is there any way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牵你的手,一向走下去 2025-02-14 19:20:19

MAPSTRUCT不支持这种忽略,但是您可以使用 创建忽略字段的复合注释

import org.mapstruct.Mapping;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "aBytes", ignore = true)
@Mapping(target = "bBytes", ignore = true)
@Mapping(target = "cBytes", ignore = true)
@Mapping(target = "dBytes", ignore = true)
@Mapping(target = "eBytes", ignore = true)
@Mapping(target = "fBytes", ignore = true)
@Mapping(target = "mergeFrom", ignore = true)
@Mapping(target = "clearField", ignore = true)
@Mapping(target = "clearOneof", ignore = true)
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "mergeUnknownFields", ignore = true)
@Mapping(target = "allFields", ignore = true)
public @interface IgnoreProtobuff {
}

应用 @ignoreprotobuff

@Mapper
public interface ProtoMapperExample {
    @IgnoreProtobuff
    ProtoMessage toMessage(Source s);
}

MapStruct does not support such ignoring, but you can use Mapping Composition to simplify your mapper. All fields which need to be ignored can be gathered into one or several annotations.

Create composite annotation for ignoring fields

import org.mapstruct.Mapping;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "aBytes", ignore = true)
@Mapping(target = "bBytes", ignore = true)
@Mapping(target = "cBytes", ignore = true)
@Mapping(target = "dBytes", ignore = true)
@Mapping(target = "eBytes", ignore = true)
@Mapping(target = "fBytes", ignore = true)
@Mapping(target = "mergeFrom", ignore = true)
@Mapping(target = "clearField", ignore = true)
@Mapping(target = "clearOneof", ignore = true)
@Mapping(target = "unknownFields", ignore = true)
@Mapping(target = "mergeUnknownFields", ignore = true)
@Mapping(target = "allFields", ignore = true)
public @interface IgnoreProtobuff {
}

Apply @IgnoreProtobuff to your mappers

@Mapper
public interface ProtoMapperExample {
    @IgnoreProtobuff
    ProtoMessage toMessage(Source s);
}
真心难拥有 2025-02-14 19:20:19

Protobuf支持已经有一个映射扩展名,可为您提供此功能。社区正在积极维护此仓库,因此我建议使用以下方式:
https://github.com/entur/mapsstruct-spi-protobuf

There is already a MapStruct extension for Protobuf support which give you this feature right out-of-the-box. Community is actively maintaining this repo, so I would suggest to instead use this:
https://github.com/entur/mapstruct-spi-protobuf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文