I have bidirectional mapping (@OneToMany Hibernate) with extra methods to ensure that both object linked. Simple example:
@Setter
class ParentDto {
List<ChildDto> childList;
}
@Setter
class ChildDto {
String text;
}
@Setter
class Parent {
List<Child> childList;
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
}
@Setter
class Child {
Parent parent;
String text;
}
Mapper:
@Mapper(componentModel = "spring")
public interface TestMapper {
Parent toEntity(ParentDto parentDto);
}
Generated:
public class TestMapperImpl implements TestMapper {
@Override
public Parent toEntity(ParentDto parentDto) {
if ( parentDto == null ) {
return null;
}
Parent parent = new Parent();
parent.setChildList( childDtoListToChildList( parentDto.getChildList() ) );
return parent;
}
protected Child childDtoToChild(ChildDto childDto) {
if ( childDto == null ) {
return null;
}
Child child = new Child();
child.setText( childDto.getText() );
return child;
}
protected List<Child> childDtoListToChildList(List<ChildDto> list) {
if ( list == null ) {
return null;
}
List<Child> list1 = new ArrayList<Child>( list.size() );
for ( ChildDto childDto : list ) {
list1.add( childDtoToChild( childDto ) );
}
return list1;
}
Main question: How to force Mapstruct to use parent.addChild (...)
to keep the bi-directional mapping between parent and List of Child.
I have a more complex structure with multiple nested children, so extensibility would be taken into account.
MapStruct has the concept of Collection Mapping Strategies. It allows you to use adders when mapping them.
e.g.
@Mapper(componentModel = "spring", collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
Parent toEntity(ParentDto parentDto);
}