I'm using Java library ModelMapper to map my local (JPA) model to a DTO version.
Model
@Entity
public class City {
@Id @GeneratedValue
private Long id;
private String postalCode;
private String name;
// getter/setter/etc.
}
DTO
public class CityDto {
private Long id;
private String postalCode;
private String name;
// getter/setter/etc.
}
Wrapper
I'm going to pass lists of these classes with an additional int, for which I created a genericly typed wrapper class.
public class Wrapper<T> {
private List<T> entities;
private Integer count;
//getter/setter/etc.
}
Question
Now, I want to convert a Wrapper<City>
into a Wrapper<CityDto>
. I thought that it's the same as converting a List<City>
into List<CityDto>
as explained in the answer to ModelMapper changes generic type on runtime - weird behavior.
@Test
public void test() {
// prepare
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);
Wrapper<City> wrapper = ...
// act
Type type = new TypeToken<Wrapper<CityDto>>() {}.getType();
Wrapper<CityDto> cityDtos = modelMapper.map(wrapper, type);
// check
Assertions.assertTrue(cityDtos.getEntities().get(0) instanceof CityDto);
}
This test fails. I get the same exception as in the aforementioned question
java.lang.ClassCastException: com.my.model.City cannot be cast to com.my.dto.CityDto
The nested list has objects of the type City
and not the expected CityDto
. What am I doing wrong?
Remark
As a workaround I am doing something like this.
Wrapper<City> wrapper = ...
List<CityDto> cityDtos = modelMapper.map(wrapper.getEntities(), new TypeToken<List<CityDto>>() {}.getType());
Wrapper<CityDto> converted = new Wrapper<>(cityDtos, wrapper.getCount());
That works, but I'd like to know why my original idea is not working.