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
1 Answer
Reset to default 1Some 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();
}
}