【问题标题】:How to map property to Integer Mapstruct in Java如何在 Java 中将属性映射到 Integer Mapstruct
【发布时间】:2019-10-17 11:05:44
【问题描述】:

我遇到了 mapstruct 映射器的问题。运行 mvn clean install(或 mvn clean compile)时,出现以下错误:

[ERROR] /mapper/EntityMapper.java:[28,7] Can't map property "java.util.List<com.socomec.tseselector.model.Source> architecture.sources
" to "java.lang.Integer architecture.sources". Consider to declare/implement a mapping method: "java.lang.Integer map(java.util.List<com.socomec.tseselector.model.Source> value)".
[ERROR] /mapper/command/TSEProjectCommandMapper.java:[21,16] Can't map property "java.lang.Integer architecture.loads" to "java.util.List<com.socomec.tseselector.model.Load> architecture.loads". Consider to declare/implement a mapping method: "java.util.List<com.socomec.tseselector.model.Load> map(java.lang.Integer value)".

问题是我不知道 mapstruct 从哪里得到这个“java.lang.Integer architecture.loads”。 我不明白这个整数是从哪里来的,正如你在我的代码中看到的那样,没有整数。到目前为止,我在使用类似的映射器时从未遇到过这个错误。

这是我的实体架构:

public class Architecture {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String imagePath;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="tse_architectures_loads",
            joinColumns = {@JoinColumn(table = "tse_architecture", name = "architecture_id")},
            inverseJoinColumns = {@JoinColumn(table = "tse_load", name = "load_id")}
    )
    private List<Load> loads;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="tse_architectures_sources",
            joinColumns = {@JoinColumn(table = "tse_architecture", name = "architecture_id")},
            inverseJoinColumns = {@JoinColumn(table = "tse_source", name = "source_id")}
    )
    private List<Source> sources;

    private String techno;

    public Architecture() {
        this.loads = new ArrayList<>();
        this.sources = new ArrayList<>();
    }

DTO

public class ArchitectureDto {
    private Long id;
    private String name;
    private String imagePath;
    private List<LoadDto> loadDtos;
    private List<SourceDto> sourceDtos;
    private String techno;

    public ArchitectureDto() {
        this.loadDtos = new ArrayList<>();
        this.sourceDtos = new ArrayList<>();
    }
}

我的映射器:

@Mapper(componentModel = "spring")
public interface ArchitectureMapper extends EntityMapper<ArchitectureDto, Architecture> {

    @Mapping(source = "loads", target = "loadDtos")
    @Mapping(source = "sources", target = "sourceDtos")
    ArchitectureDto toDto(Architecture architecture);
}

实体映射器:

public interface EntityMapper<D, E> {

    /**
     * Map a DTO to an Entity
     *
     * @param dto the dto to map
     * @return an Entity
     */
    E toEntity(D dto);

    /**
     * Map an Entity to a DTO
     *
     * @param entity to map to a DTO
     * @return a DTO
     */
    D toDto(E entity);

    /**
     * Map a List of DTOs to a List of Entities
     *
     * @param dtoList the list to map
     * @return a list of Entities
     */
    List<E> toEntity(List<D> dtoList);

    /**
     * Map a list of Entities to a list of DTOs
     *
     * @param entityList the list to map
     * @return a list of DTOs
     */
    List<D> toDto(List<E> entityList);
}

在这里查看有关mapstruct的文档和其他问题,到目前为止我还没有找到解决方案。

我正在添加我的负载和源类 加载:

public class Load {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String type;
    private String unity;
    private Long sourcePriority1;
    private Long SourcePriority2;
    private Long SourcePriority3;
    private Long kvaValue;
    private Long kwValue;
    private Long pfValue;
    private Long aValue;
    private Long iccValue;

    @JsonIgnore
    @ManyToMany(mappedBy = "loads")
    private List<TSEProject> tseProjects;

    @JsonIgnore
    @ManyToMany(mappedBy = "loadList")
    private List<Architecture> architectures;

    public Load() {
        this.architectures = new ArrayList<>();
        this.tseProjects = new ArrayList<>();
    }

来源:

public class Source {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String type;
    private String unity;
    private Long quantity;
    private Long kvaValue;
    private Long kwValue;
    private Long pfValue;
    private Long aValue;

    @JsonIgnore
    @ManyToMany(mappedBy = "sources")
    private List<TSEProject> tseProjects;

    @JsonIgnore
    @ManyToMany(mappedBy = "sourceList")
    private List<Architecture> architectures;

    public Source() {
        this.architectures = new ArrayList<>();
        this.tseProjects = new ArrayList<>();
    }

}

和 DTO

@Data
public class LoadDto {
    private Long id;
    private String name;
    private String type;
    private String unity;
    private Long sourcePriority1;
    private Long SourcePriority2;
    private Long SourcePriority3;
    private Long kvaValue;
    private Long kwValue;
    private Long pfValue;
    private Long aValue;
    private Long iccValue;
    private List<Long> tseProjectsId;

    public LoadDto() {
        this.tseProjectsId = new ArrayList<>();
    }

}
@Data
public class SourceDto {

    private Long id;
    private String name;
    private String type;
    private String unity;
    private Long quantity;
    private Long kvaValue;
    private Long kwValue;
    private Long pfValue;
    private Long aValue;

}

【问题讨论】:

  • 您确定您使用的是最新/正确版本的实体和 DTO 类吗? MapStruct 似乎认为 DTO 中的字段sourcesjava.lang.Integer,但这与ArchitectureDto 的来源不对应。 DTO 中是否有 getter 和 setter 方法? (你在上面的代码中遗漏了?)
  • 我确实忽略了 getter 和 setter。我正在使用 Lombok 通过 @Data 生成 getter 和 setter。
  • 据我所知,字段 architecture.loads 从来都不是整数。如果我没有使用最新版本,我将如何解决这个问题?

标签: java spring mapstruct


【解决方案1】:

我猜你需要解决更多问题。尝试帮助 MapStruct 并定义一个额外的映射方法,如下所示:

Mapper(componentModel = "spring")
public interface ArchitectureMapper extends EntityMapper<ArchitectureDto, Architecture> {

    @Mapping(source = "loads", target = "loadDtos")
    @Mapping(source = "sources", target = "sourceDtos")
    ArchitectureDto toDto(Architecture architecture);

    // first try with all properties ignored
    // @Mapping( target = "id", ignore = true ) etc.
    SourceDto toDto(Source source);

    // first try with all properties ignored
    // @Mapping( target = "id", ignore = true ) etc.
    LoadDto toDto(Load load);

}

问题在于 MapStruct 尝试根据属性名称自动映射这些对象。如果它在某个地方发现了相同的名称,它会尝试进行类型转换或使用现有的映射方法来完成它的工作。它甚至会尝试 2 个步骤(先是转换,然后是一个方法),这有时会导致这些结果。

您可以提供一些 MapStruct 尝试自行生成的映射,然后再次忽略上面示例中所示的所有属性。一根一根去掉忽略线,看看 MapStruct 什么时候开始报错。

如果它又是一个对象图,您可以应用类似的策略。

这样的调试有点乏味,但可能在您的对象图中您会发现问题的深处。然后,您可以再次删除所有签名,解决您的问题的签名除外,最大限度地利用代码生成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    相关资源
    最近更新 更多