【问题标题】:MapStruct to not generate mappings for fields marked with specific annotationMapStruct 不会为标有特定注释的字段生成映射
【发布时间】:2021-12-23 11:19:42
【问题描述】:

我正在处理我无法修改的框架代码,最终在映射过程中抛出 NullPointerException,因为 MapStruct 认为它应该使用在超类中定义的 getter。

有没有办法告诉 MapStruct 忽略所有标有 @JsonIgnore(杰克逊库注释)的 getter?


更多上下文

为了提供一点代码,这里是 MapStruct 生成的部分实现:

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

NPE 是从 target.getChangedProperties() 中抛出的,因为有一些未初始化的变量正在被访问。然而,实际上,我什至不希望这个 getter 成为 MapStruct 实现的一部分。 (事实上​​,这个 getter 并不是特定变量的 getter,而更像是一个“实用程序 getter”,所以我想知道 MapStruct 为什么要尝试使用它。)

我的映射类如下所示:

@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
    }
}

我的 MapStruct 界面

我没有自定义映射器的配置。我的界面是:

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

    MyEntity boToBo(MyEntity destination);

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

我曾考虑使用 @BeanMapping(ignoreByDefault = true),然后单独列出每个字段以确保不使用额外的 getter,但这远不是一个令人满意的解决方案,因为我必须这样做。

【问题讨论】:

    标签: java mapstruct


    【解决方案1】:

    好吧,即使 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);
    }
    

    【讨论】:

    • 只需为此添加更多上下文。 MapStruct 不查看字段。 MapStruct 查看 Java Bean 规范定义的属性,现在它还支持公共字段和 Java 记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    相关资源
    最近更新 更多