MapStruct - неверный тип данных учитывается при создании класса реализации mapper - PullRequest
0 голосов
/ 26 июня 2018

Я новичок в MapStruct и поэтому могу делать что-то очень глупое. Извиняюсь заранее. Я использую Spring Boot 1.5.3 и JHipster для генерации кода с использованием JDL. MapStruct используется для отображения сущности в DTO и наоборот.

У меня есть объект Currency, который содержит первичную информацию о валюте, такую ​​как код валюты, символ валюты и т. Д. Класс CurrencyTl содержит описательную информацию о валюте, такую ​​как имя, описание и т. Д., На различных языках, поддерживаемых приложением. Языки содержат определение языков, поддерживаемых приложением.

Валюта

public class Currency extends AbstractEffectiveEntity {
  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid2")
  @Column(name = "id", columnDefinition = "CHAR", length = 36, nullable = false)
  private String id;

  @Column(name = "currency_code", columnDefinition = "CHAR", length = 5, nullable = false, updatable = false)
  private String currencyCode;

  @Column(name = "currency_symbol", columnDefinition = "VARCHAR", length = 10, nullable = false, updatable = false)
  private String currencySymbol;

  @Column(name = "installed_flag", columnDefinition = "CHAR", length = 1, nullable = false)
  private String installedFlag;

  @OneToMany(mappedBy = "currency")
  @JsonIgnore
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  private Set<CurrencyTl> currencyTls = new HashSet<>();

  // Getters and Setters (Avoided for brevity)
}

CurrencyTl

public class CountryTl extends AbstractEntity {
  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid2")
  @Column(columnDefinition = "CHAR", length = 36, nullable = false)
  private String id;

  @Column(name = "entity_name", columnDefinition = "VARCHAR", length = 120, nullable = false)
  private String entityName;

  @Column(name = "entity_desc", columnDefinition = "VARCHAR", length = 256, nullable = true)
  private String entityDesc;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "country_id", nullable = false)
  private Country country;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "language_id", nullable = false)
  private Language language;

  // Getters and Setters
}

Язык

public class Language extends AbstractEffectiveEntity {

  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid2")
  @Column(name = "id", columnDefinition = "CHAR", length = 36, nullable = false)
  private String id;

  @Column(name = "language_code", columnDefinition = "CHAR", length = 5, nullable = false)
  private String languageCode;

  @Column(name = "language_name", columnDefinition = "VARCHAR", length = 80, nullable = false)
  private String languageName;

  // Getters and Setters
}

Интерфейс Mapper

public interface EntityMapper<D, E> {
  E toEntity(D dto);
  D toDto(E entity);
  List<E> toEntity(List<D> dtoList);
  List<D> toDto(List<E> entityList);
}

Я создал интерфейс Mapper для Country, Language и CountryTl, расширив вышеуказанный интерфейс. Интерфейс CountryTlMapper определяется следующим образом:

CountryTlMapper

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.WARN, uses = {LanguageMapper.class, CurrencyMapper.class})

public interface CurrencyTlMapper extends EntityMapper<CurrencyTlDTO, CurrencyTl> {

  @Mapping(source = "language.id", target = "languageId")
  @Mapping(source = "currency.id", target = "currencyId")
  @Override
  CurrencyTlDTO toDto(CurrencyTl currencyTl);

  @Mapping(source = "languageId", target = "language")
  @Mapping(source = "currencyId", target = "currency")
  @Override
  CurrencyTl toEntity(CurrencyTlDTO currencyTlDTO);

  default CurrencyTl fromId(String id) {
    if (id == null) {
      return null;
    }
    CurrencyTl currencyTl = new CurrencyTl();
    currencyTl.setId(id);
    return currencyTl;
  }
}

Вышеуказанные результаты в MapStruct генерируют класс реализации следующим образом:

CurrencyTlMapperImpl

@Component
public class CurrencyTlMapperImpl implements CurrencyTlMapper {
  @Autowired
  private LanguageMapper languageMapper;
  @Autowired
  private CurrencyMapper currencyMapper;

  @Override
  public List<CurrencyTl> toEntity(List<CurrencyTlDTO> dtoList) {
    // Removed for brevity
    return list;
  }

  @Override
  public List<CurrencyTlDTO> toDto(List<CurrencyTl> entityList) {
    // Removed for brevity
    return list;
  }

  @Override
  public CurrencyTlDTO toDto(CurrencyTl currencyTl) {
    if ( currencyTl == null ) {
        return null;
    }
    CurrencyTlDTO currencyTlDTO = new CurrencyTlDTO();
    String id = currencyTlLanguageId( currencyTl );
    if ( id != null ) {
      currencyTlDTO.setLanguageId( Long.parseLong( id ) );
    }
    String id1 = currencyTlCurrencyId( currencyTl );
    if ( id1 != null ) {
      currencyTlDTO.setCurrencyId( Long.parseLong( id1 ) );
    }
    currencyTlDTO.setId( currencyTl.getId() );
    currencyTlDTO.setEntityName( currencyTl.getEntityName() );
    currencyTlDTO.setEntityDesc( currencyTl.getEntityDesc() );
    return currencyTlDTO;
  }

  @Override
  public CurrencyTl toEntity(CurrencyTlDTO currencyTlDTO) {
    if ( currencyTlDTO == null ) {
      return null;
    }
    CurrencyTl currencyTl = new CurrencyTl();
    if ( currencyTlDTO.getLanguageId() != null ) {
        currencyTl.setLanguage( languageMapper.fromId( String.valueOf( currencyTlDTO.getLanguageId() ) ) );
    }
    if ( currencyTlDTO.getCurrencyId() != null ) {
        currencyTl.setCurrency( currencyMapper.fromId( String.valueOf( currencyTlDTO.getCurrencyId() ) ) );
    }
    currencyTl.setId( currencyTlDTO.getId() );
    currencyTl.setEntityName( currencyTlDTO.getEntityName() );
    currencyTl.setEntityDesc( currencyTlDTO.getEntityDesc() );
    return currencyTl;
  }

  private String currencyTlLanguageId(CurrencyTl currencyTl) {
    if ( currencyTl == null ) {
        return null;
    }
    Language language = currencyTl.getLanguage();
    if ( language == null ) {
        return null;
    }
    String id = language.getId();
    if ( id == null ) {
        return null;
    }
    return id;
  }

  private String currencyTlCurrencyId(CurrencyTl currencyTl) {
    if ( currencyTl == null ) {
        return null;
    }
    Currency currency = currencyTl.getCurrency();
    if ( currency == null ) {
        return null;
    }
    String id = currency.getId();
    if ( id == null ) {
        return null;
    }
    return id;
  }
}

CurrencyDTO

public class CurrencyDTO extends AbstractEffectiveEntityDTO implements Serializable {

  private static final long serialVersionUID = -3989102119178748641L;

  @Size(max = 36)
  private String id;

  @NotNull
  @Size(min = 2, max = 5)
  private String currencyCode;

  @NotNull
  @Size(min = 2, max = 10)
  private String currencySymbol;

  @NotNull
  @Size(max = 1)
  private String installedFlag;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getCurrencyCode() {
    return currencyCode;
  }

  public void setCurrencyCode(String currencyCode) {
    this.currencyCode = currencyCode;
  }

  public String getCurrencySymbol() {
    return currencySymbol;
  }

  public void setCurrencySymbol(String currencySymbol) {
    this.currencySymbol = currencySymbol;
  }

  public String getInstalledFlag() {
    return installedFlag;
  }

  public void setInstalledFlag(String installedFlag) {
    this.installedFlag = installedFlag;
  }
}

CurrencyTlDTO

public class CurrencyTlDTO implements Serializable {

  private static final long serialVersionUID = 1142708918251175249L;

  @Size(max = 36)
  private String id;

  @NotNull
  @Size(max = 120)
  private String entityName;

  @Size(max = 256)
  private String entityDesc;

  private Long languageId;

  private Long currencyId;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getEntityName() {
    return entityName;
  }

  public void setEntityName(String entityName) {
    this.entityName = entityName;
  }

  public String getEntityDesc() {
    return entityDesc;
  }

  public void setEntityDesc(String entityDesc) {
    this.entityDesc = entityDesc;
  }

  public Long getLanguageId() {
    return languageId;
  }

  public void setLanguageId(Long languageId) {
    this.languageId = languageId;
  }

  public Long getCurrencyId() {
    return currencyId;
  }

  public void setCurrencyId(Long currencyId) {
    this.currencyId = currencyId;
  }
}

LanguageDTO

public class LanguageDTO extends AbstractEffectiveEntityDTO implements Serializable {

  private static final long serialVersionUID = 8419729079888691835L;

  private String id;

  @NotNull
  @Size(min = 2, max = 5)
  private String languageCode;

  @NotNull
  @Size(min = 5, max = 80)
  private String languageName;

  @NotNull
  @Size(min = 3, max = 80)
  private String languageNativeName;

  @Size(max = 256)
  private String languageIcon;

  @NotNull
  @Size(max = 1)
  private String installedFlag;

  @NotNull
  @Size(max = 1)
  private String defaultFlag;

  public LanguageDTO() {
    // Emply constructor need for Jaskson
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getLanguageCode() {
    return languageCode;
  }

  public void setLanguageCode(String languageCode) {
    this.languageCode = languageCode;
  }

  public String getLanguageName() {
    return languageName;
  }

  public void setLanguageName(String languageName) {
    this.languageName = languageName;
  }

  public String getLanguageNativeName() {
    return languageNativeName;
  }

  public void setLanguageNativeName(String languageNativeName) {
    this.languageNativeName = languageNativeName;
  }

  public String getLanguageIcon() {
    return languageIcon;
  }

  public void setLanguageIcon(String languageIcon) {
    this.languageIcon = languageIcon;
  }

  public String getInstalledFlag() {
    return installedFlag;
  }

  public void setInstalledFlag(String installedFlag) {
    this.installedFlag = installedFlag;
  }

  public String getDefaultFlag() {
    return defaultFlag;
  }

  public void setDefaultFlag(String defaultFlag) {
    this.defaultFlag = defaultFlag;
  }
}

Я не уверен, что заставило MapStruct трактовать id языка и валюты как Long !! Эта строка завершается с ошибкой currencyTlDTO.setCurrencyId( Long.parseLong( id1 ) ), поскольку все атрибуты id являются строковыми и хранят значение UUID в форме 1edd1914-783d-11e8-9e18-9801a7b6295b. Может кто-нибудь подсказать, пожалуйста, где я не прав и как можно исправить вышесказанное, когда MapStruct принимает тип данных атрибута, как определено? Заранее спасибо.

1 Ответ

0 голосов
/ 27 июня 2018

Не уверен, что именно проблема.Однако CurrencyTlDTO имеет свойства типа Long для currencyId

. Вы явно сопоставляете это с:

@Mapping(source = "language.id", target = "languageId")
@Mapping(source = "currency.id", target = "currencyId")

А в CurrencyTlDTO у вас есть

public Long getCurrencyId() {
  return currencyId;
}

public void setCurrencyId(Long currencyId) {
  this.currencyId = currencyId;
}
...