简体   繁体   English

MapStruct 不会为标有特定注释的字段生成映射

[英]MapStruct to not generate mappings for fields marked with specific annotation

I'm dealing with framework code that I cannot modify and which ends up throwing a NullPointerException during mapping because MapStruct thinks it should use a getter defined in a superclass.我正在处理无法修改的框架代码,最终在映射期间抛出NullPointerException异常,因为 MapStruct 认为它应该使用在超类中定义的 getter。

Is there a way to tell MapStruct to ignore all getters marked with @JsonIgnore (a jackson library annotation) ?有没有办法告诉 MapStruct 忽略所有标有@JsonIgnore (杰克逊库注释)的 getter?


Some more context更多上下文

To provide a bit of code, here is part of the generated implementation by MapStruct:为了提供一些代码,这里是 MapStruct 生成的实现的一部分:

        if ( target.getChangedProperties() != null ) {
            target.getChangedProperties().clear();
            List<Property> list = src.getChangedProperties();
            if ( list != null ) {
                target.getChangedProperties().addAll( list );
            }
        }

The NPE is thrown from within target.getChangedProperties() because there are some uninitialized variables being accessed. NPE 从target.getChangedProperties()抛出,因为有一些未初始化的变量被访问。 However, in reality, I don't even want this getter to be part of MapStruct's implementation .然而,实际上,我什至不希望这个 getter 成为 MapStruct 实现的一部分 (In fact, that getter isn't a getter for a specific variable, but more of a "utility getter", so I do wonder why MapStruct is trying to use it.) (实际上,那个 getter 不是特定变量的 getter,而是更多的“实用 getter”,所以我想知道 MapStruct 为什么要尝试使用它。)

My mapped class would look like:我的映射类看起来像:

@Entity
@Table(name = "myentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyEntity extends TheFrameworkSuperClass {

  @Id
  private String id;

  private String foo;
}
@MappedSuperclass
@JsonSerialize(include = JsonSerialize.Inclusion.NON_DEFAULT)
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class TheFrameworkSuperClass {

    @Version
    @JsonProperty(value = "Version")
    private Long version;

    @Transient
    @JsonIgnore
    protected UnitOfWorkChangeSet changes;

    @Override
    @JsonIgnore
    public List<Property> getChangedProperties() {
        // stuff happening before
        this.changes.getObjectChangeSetForClone(this); // throws NPE
        // stuff happening after
    }
}

My MapStruct interface我的 MapStruct 界面

I have no customization of the mapper's configs.我没有自定义映射器的配置。 And my interface is:我的界面是:

@Mapper(componentModel = "spring")
public interface MyMapper {

    MyEntity boToBo(MyEntity destination);

    void updateBo(MyEntity src, @MappingTarget MyEntity target);
}

I contemplated using @BeanMapping(ignoreByDefault = true) and then listing each field individually to make sure no extra getters are used, but that is far from being a satisfying solution due to the amount of times I'll have to do that.我考虑使用@BeanMapping(ignoreByDefault = true)然后单独列出每个字段以确保没有使用额外的 getter,但这远不是一个令人满意的解决方案,因为我必须这样做的次数@BeanMapping(ignoreByDefault = true)

Well, turns out even though the changedProperties field does not exist, since MapStruct picks up getChangedProperties() as a getter, you can nonetheless tell MapStruct to ignore that non-existing field...好吧,事实证明即使changedProperties字段不存在,因为 MapStruct 选择getChangedProperties()作为 getter,您仍然可以告诉 MapStruct 忽略该不存在的字段......

@Mapper(componentModel = "spring")
public interface MyMapper {

    @Mapping(target = "changedProperties", ignore = true)
    MyEntity boToBo(MyEntity destination);

    @Mapping(target = "changedProperties", ignore = true)
    void updateBo(MyEntity src, @MappingTarget MyEntity target);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM