最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - ModelMapper and custom field mapping with .addMapping - Stack Overflow

programmeradmin0浏览0评论

I started using ModelMapper to map Dtos to entities in my project. I want do define a custom mapper for RoomTypeDto class. I have problem with custom mapping of field description.

my code:

    var modelMapper = new ModelMapper();
    modelMapper.getConfiguration()
            .setMatchingStrategy(MatchingStrategies.STRICT)
            .setPreferNestedProperties(false);
    modelMapper.createTypeMap(RoomType.class, RoomTypeDto.class)
            .addMapping(rt -> rt.getDescription().map(Description::getDescription).orElse(null), RoomTypeDto::setDescription);

throws following exception:

Caused by: org.modelmapper.internal.ErrorsException: null
at org.modelmapper.internal.Errors.toException(Errors.java:253)
at org.modelmapper.internal.ReferenceMapExpressionImpl.visitSource(ReferenceMapExpressionImpl.java:113)
at org.modelmapper.internal.ReferenceMapExpressionImpl.map(ReferenceMapExpressionImpl.java:66)
at org.modelmapper.internal.TypeMapImpl.addMapping(TypeMapImpl.java:260)
at pl.ekoncept.room.mapper.RoomTypeReadMapper.<init>(RoomTypeReadMapper.java:20)

this code works:

modelMapper.createTypeMap(RoomType.class, RoomTypeDto.class)
          .addMappings(m -> m.skip(RoomTypeDto::setDescription));

How to make custom mapping for field description.getDesctiption in Roomtype class to field description in RoomtypeDto class?

UPDATE:

RoomTypeDto:

@Data
@NoArgsConstructor
public class RoomTypeDto {
    private String description;
    [...]
}

RoomType:

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
public class RoomTypeDto {
    private Description description;
    [...]
    public Optional<Description> getDescription() {
        return Optional.ofNullable(description);
    }
    [...]
}

Description:

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
public class Description {
    private String description;
    [...]
}

I started using ModelMapper to map Dtos to entities in my project. I want do define a custom mapper for RoomTypeDto class. I have problem with custom mapping of field description.

my code:

    var modelMapper = new ModelMapper();
    modelMapper.getConfiguration()
            .setMatchingStrategy(MatchingStrategies.STRICT)
            .setPreferNestedProperties(false);
    modelMapper.createTypeMap(RoomType.class, RoomTypeDto.class)
            .addMapping(rt -> rt.getDescription().map(Description::getDescription).orElse(null), RoomTypeDto::setDescription);

throws following exception:

Caused by: org.modelmapper.internal.ErrorsException: null
at org.modelmapper.internal.Errors.toException(Errors.java:253)
at org.modelmapper.internal.ReferenceMapExpressionImpl.visitSource(ReferenceMapExpressionImpl.java:113)
at org.modelmapper.internal.ReferenceMapExpressionImpl.map(ReferenceMapExpressionImpl.java:66)
at org.modelmapper.internal.TypeMapImpl.addMapping(TypeMapImpl.java:260)
at pl.ekoncept.room.mapper.RoomTypeReadMapper.<init>(RoomTypeReadMapper.java:20)

this code works:

modelMapper.createTypeMap(RoomType.class, RoomTypeDto.class)
          .addMappings(m -> m.skip(RoomTypeDto::setDescription));

How to make custom mapping for field description.getDesctiption in Roomtype class to field description in RoomtypeDto class?

UPDATE:

RoomTypeDto:

@Data
@NoArgsConstructor
public class RoomTypeDto {
    private String description;
    [...]
}

RoomType:

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
public class RoomTypeDto {
    private Description description;
    [...]
    public Optional<Description> getDescription() {
        return Optional.ofNullable(description);
    }
    [...]
}

Description:

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
public class Description {
    private String description;
    [...]
}
Share Improve this question edited Feb 5 at 12:27 Olek asked Feb 5 at 11:36 OlekOlek 35911 silver badges24 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 1

Some testing shows that .addMapping doesn't accept custom code for the SourceGetter, and a custom org.modelmapper.Converter that converts Optional<Description> into a String, is required.

        Converter<Optional<Description>, String> descriptionConverter = context ->
                context
                        .getSource()
                        .map(Description::getDescription)
                        .orElse(null);

        var modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setMatchingStrategy(MatchingStrategies.STRICT)
                .setPreferNestedProperties(false);

        modelMapper.createTypeMap(RoomType.class, RoomTypeDto.class)
                 // apply the converter here
                .addMappings(m -> m.using(descriptionConverter)
                        .map(RoomType::getDescription, RoomTypeDto::setDescription));

Debugging shows that the error comes from org.modelmapper.internal.ReferenceMapExpressionImpl starting on line 103:

  private void visitSource(SourceGetter<S> sourceGetter) {
    notNull(sourceGetter, "sourceGetter");
    try {
      Object sourceProperty = sourceGetter.get(source);
      if (source == sourceProperty)
        collector.mapFromSource(typeMap.getSourceType());
      if (collector.isNoSourceGetter())
        collector.mapFromConstant(sourceProperty);
    } catch (NullPointerException e) {
      if (collector.getProxyErrors().hasErrors())       
        throw collector.getProxyErrors().toException(); // this line
      throw e;
    } catch (ErrorsException e) {
      throw e.getErrors().toConfigurationException();
    }
  }
发布评论

评论列表(0)

  1. 暂无评论