当前位置: 首页 > 知识库问答 >
问题:

无法用mapstruct将列表映射到列表

乐宜民
2023-03-14
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.sql.Timestamp;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder(toBuilder = true)
    @Table(name = "source")
    @Entity(name = "Source")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class Source implements Serializable {

        private static final long serialVersionUID = 964150155782995534L;

        @Id
        @JsonIgnore
        @Column(name = "id")
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SourceSeq")
        @SequenceGenerator(sequenceName = "source_id_seq", allocationSize = 1, name = "SourceSeq")
        private long id;

        @NotNull
        @Size(min = 36, max = 36)
        @Column(name = "uuid", nullable = false, length = 36)
        private String uuid;

        @Column(name = "user_id")
        private Long userId;

        @Column(name = "username")
        private String username;

        @Column(name = "user_org_id")
        private Long userOrgId;

        @Column(name = "user_org_name")
        private String userOrgName;

        @Column(name = "account_number")
        private Integer accountNumber;

        @Column(name = "account_name")
        private String accountName;

        @Column(name = "billing_delay")
        private Integer billingDelay;

        @Column(name = "default_billing_delay")
        private Integer defaultBillingDelay;

        @Column(name = "billing_enabled")
        private Boolean billingEnabled = true;

        @JsonIgnore
        @CreationTimestamp
        @Column(name = "created_date")
        private Timestamp createdDate;

        @JsonIgnore
        @UpdateTimestamp
        @Column(name = "updated_date")
        private Timestamp updatedDate;
    }
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Target implements Serializable {

    private static final long serialVersionUID = 8939532280496355293L;

    @ApiModelProperty(hidden = true)
    private String uuid;

    @ApiModelProperty(value = "user ID", example = "123456", dataType = "int64", position = 1)
    private Long userId;

    @ApiModelProperty(value = "username", example = "myUser", position = 2)
    private String username;

    @ApiModelProperty(hidden = true)
    private String firstName;

    @ApiModelProperty(hidden = true)
    private String lastName;

    @ApiModelProperty(value = "user organization ID", example = "71836", dataType = "int64", position = 3)
    private Long userOrgId;

    @ApiModelProperty(value = "user organization name", example = "Org Inc", position = 4)
    private String userOrgName;

    @ApiModelProperty(value = "account number", example = "987654", position = 5)
    private Integer accountNumber;

    @ApiModelProperty(value = "account name", example = "My Mapping Acc", position = 6)
    private String accountName;

    @ApiModelProperty(value = "billing delay (in days)", example = "60", position = 7)
    private Integer billingDelay;

    @ApiModelProperty(value = "default billing delay (in days)", example = "30", position = 8)
    private Integer defaultBillingDelay;

    @ApiModelProperty(value = "is billing enabled?", example = "true", position = 9)
    private Boolean billingEnabled = true;

    @ApiModelProperty(hidden = true)
    private Date createdDate;
}
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.List;

@Mapper
public interface MyMapper {

    MyMapper MAPPER = Mappers.getMapper(MyMapper.class);


    // Target toTarget(Source source);
    // I have tried using this as well but my target mapped list only contains billingEnabled = true for every object in the response list. MapperImpl class also included below. Without toTarget method get a compilation error (also included below)
    // Response: 
        /*[

      {
        "billingEnabled": true
      },
      {
        "billingEnabled": true
      },
      {
        "billingEnabled": true
      }
    ]*/

    List<Target> toTargets(List<Source> sources);
}
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2019-09-16T00:06:14-0700",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)"
)
public class MyMapperImpl implements MyMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        return target;
    }

    @Override
    public List<Target> toTargets(List<Source> sources) {
        if ( sources == null ) {
            return null;
        }

        List<Target> list = new ArrayList<Target>( sources.size() );
        for ( Source source : sources ) {
            list.add( toTarget( source ) );
        }

        return list;
    }
}

错误:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project my-project: Compilation failure
[ERROR] /Users/user8812/workspace/my-project-/src/main/java/MyMapper.java:[17,23] Can't map Collection element "Source source" to "Target target". Consider to declare/implement a mapping method: "Target map(Source value)".

我希望在target列表中映射相同的字段名,而不需要另一个单独的toTarget方法,就像在另一个项目中使用旧的mapstruct版本时一样。

共有1个答案

胡鸿羲
2023-03-14

MapStruct在编译过程中引发的异常告诉您如何修复它:

无法将集合元素“源源”映射到“目标目标”。考虑声明/实现一个映射方法:“目标映射(源值)”。

您甚至可以将此方法签名放置在您向我们展示的同一个接口中。

@BeanMapping(ignoreByDefault = false)
 类似资料:
  • ...但我得到: 我不知道如何应用这些信息。首先,我认为我需要为列表声明一些额外的映射(在同一个映射器类中),所以MapStruct知道如何像这样映射列表类型的每个字段: ...但我收到错误消息

  • 下面是我的DTO。 源DTO 目标DTO

  • 我是Mapstruct的新手。我试图将列表转换为地图,我在网上搜索了很多,我有一些解决方案,比如它还没有在mapstruct中实现。如果有人能提供一些替代解决方案,我将很高兴。所有我希望转换映射如下: 现在是否可以使用MapStruct来实现?

  • 如何将字符串映射到列表,并将列表映射到字符串? 考虑到我们有以下班级 在Dozer和Orika中,我们可以使用以下代码行轻松映射 如何在MapStruct中进行相同类型的映射?在哪里可以找到有关mapstruct的更多示例?

  • 给定: 我想把所有的车都标出来。将轮胎分为单独的轮胎板。我知道我可以做一个

  • 我最近开始使用mapstruct,在编码时我坚持使用一个场景。为了解决下面默认方法之间的模糊性,我试图在列表中使用“限定由” 但是第1行显示错误,因为需要指定“target”。我不确定这里的目标应该是什么,因为Line是一个集合对象。即使我不使用@mapping,mapstuct也会生成mapper实现。我阅读了mapstuct文档,但对这个场景了解不多。如何在列表上使用命名注释来明确表示这是要使