Hi
I've got a tree-like structure of entities that I'm trying to map to DTOs using ModelMapper. The trick is that I'm trying to break the graph after the first parent.
Following is a example of what I'm trying to do (I'm trying to get it to turn green :-) . I've got a Category entity which has a name and a parent Category. I want my DTO to have a link to it's parent but don't want the latter to have it's own parent (so that I don't get the whole hierarchy)
The trouble is that ModelMapper does not map my DTO's parent because it's of a different type; I declared it as being a AbstractDTO rather that a CategoryDTO in order to break the recursion. If I DO declare my parent as a CategoryDTO, the mapping works fine but I will get all of my parents and grand parents (which I do not want).
Anybody knows how I could fix this?
import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import org.modelmapper.ModelMapper;
public class CategoryTest {
public static class Category {
private String uid = UUID.randomUUID().toString();
private String name;
private Category parent;
public Category () {}
public Category(String name, Category parent) {
this.name = name;
this.parent = parent;
}
public String getUid() {return uid;}
public void setUid(String uid) {this.uid = uid;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Category getParent() {return parent;}
public void setParent(Category parent) {this.parent = parent;}
}
public static class AbstractDTO {
private String uid;
private String name;
public String getUid() {return uid;}
public void setUid(String uid) {this.uid = uid;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
public static class CategoryDTO extends AbstractDTO {
private AbstractDTO parent;
public AbstractDTO getParent() {return parent;}
public void setParent(AbstractDTO parent) {this.parent = parent;}
}
@Test
public void simpleTest() {
Category dto = new Category("Test1",null);
CategoryDTO entity = new ModelMapper().map(dto, CategoryDTO.class);
Assert.assertEquals("Test1", entity.getName());
Assert.assertEquals(dto.getUid(), entity.getUid());
}
@Test
public void withParentTest() {
Category dto = new Category("child",new Category("parent", new Category("root", null)));
CategoryDTO entity = new ModelMapper().map(dto, CategoryDTO.class);
Assert.assertEquals("child", entity.getName());
Assert.assertEquals(dto.getUid(), entity.getUid());
Assert.assertNotNull(entity.getParent()); // my child should have a parent dto
Assert.assertTrue(entity.getParent() instanceof AbstractDTO); // and it should be an AbstractDTO to stop
}
}private ModelMapper getModelMapper() {
ModelMapper map = new ModelMapper();
map.addConverter(new AbstractConverter<Category, AbstractDTO>() {
@Override
protected AbstractDTO convert(Category source) {
if (source == null) return null;
AbstractDTO dto = new AbstractDTO();
dto.setUid(source.getUid());
dto.setName(source.getName());
return dto;
}
});
return map;
}
private ModelMapper getModelMapper() {
ModelMapper map = new ModelMapper();
map.addConverter(new AbstractConverter<Category, AbstractDTO>() {
@Override
protected AbstractDTO convert(Category source) {
if (source == null) return null;
AbstractDTO dto = new AbstractDTO();
dto.setUid(source.getUid());
dto.setName(source.getName());
return dto;
}
});
return map;
}