fjy8018
fjy8018

Reputation: 85

Mapstruct does not automatically map the base type constructor

environment: java: 17.0.1 mapstruct: 1.4.2.Final

example:

public record RecordId(Long id) {
}

mapper

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

    @Mapping(target = "id")
    RecordId convertRecord(Long id);

    @Mapping(source = "id",target = ".")
    Long convertRecord(RecordId id);

    List<RecordId> convertRecord(List<Long> id);
}

But compile with error

java: Ambiguous constructors found for creating java.lang.Long. Either declare parameterless constructor or annotate the default constructor with an annotation named @Default.

I can't modify the constructor of the Long type

How should I config it?

Upvotes: 1

Views: 1691

Answers (1)

Ben Zegveld
Ben Zegveld

Reputation: 1516

You are not dealing with a mapping here, but with a container object (an object containing a single field). It is better to manually implement this, the list mappings are possible with mapstruct.

@Mapper(componentModel = "spring")
public interface RecordIdAssembler {
    default RecordId convertRecord(Long id) {
        return new RecordId(id);
    }

    default Long convertRecord(RecordId id) {
        return id.id();
    }
    List<RecordId> convertToRecord(List<Long> id);
    List<Long> convertFromRecord(List<RecordId> id);
}

an other option is to handle this where you have RecordId and Long as fields and convert them with mappings. For example in the following situation:

class RecordDto {
  private Long id;
// other fields
// getters & setters
}
class RecordEntity {
  private RecordId recId;
// other fields
// getters & setters
}
@Mapper
interface RecordMapper {
  @Mapping(source = "id", target = "recId.id");
  RecordEntity map(RecordDto dto);

  @InheritInverseConfiguration
  RecordDto map(RecordEntity entity);
}

Upvotes: 2

Related Questions