MapStruct:合并父对象时调用子对象的合并
MapStruct: Call merge of Child object while merging Parent object
我有两种合并方法,一种用于父对象,一种用于子对象
@Mappings({
@Mapping(target="childs", source="childs")
})
void merge(@MappingTarget Target result, Source request);
void merge(@MappingTarget ChildTarget result, ChildSource request);
现在MapStruct生成第一个合并方法的实现如下
@Override
public void merge(Target result, Source request) {
if ( request == null ) {
return;
}
if ( result.getChilds() != null ) {
// I want to instruct MapStruct to call merge for Child object
List<ChildTarget> list = childSourceListToChildTargetList( request.getChilds() );
if ( list != null ) {
result.getChilds().clear();
result.getChilds().addAll( list );
}
else {
result.setChilds( null );
}
}
else {
List<ChildTarget> list = childSourceListToChildTargetList( request.getChilds() );
if ( list != null ) {
result.setChilds( list );
}
}
}
protected List<ChildTarget> childSourceListToChildTargetList(List<ChildSource> list) {
if ( list == null ) {
return null;
}
List<ChildTarget> list1 = new ArrayList<ChildTarget>( list.size() );
for ( ChildSource childSource : list ) {
list1.add( childSourceToChildTarget( childSource ) );
}
return list1;
}
我尝试了各种注释,但无法找到任何确切的解决方案
如果我理解正确你正在尝试做什么,一种可能的解决方案是使用 expressions:
@Mappings({
@Mapping(target="childs",
expression = "java( mergeChilds(target, request) )")
})
void merge(@MappingTarget Target result, Source request);
请注意 mergeChilds
必须具有以下签名:
List<ChildTarget> mergeChilds(Target target, Source source)
例如,它可以是您界面中的一个 default
方法,并且必须包含您的域特定逻辑来处理合并。
MapStruct 无法正确执行此操作。查看 here 原因。如何合并集合与用例密切相关(正如您已经发现的那样)。
但是你总是可以自己做,MapStruct 会select那个方法。
@Mapping(target="childs", source="childs") // you can omit @Mappings in java8
void merge(@MappingTarget Target result, Source request);
default void merge(@MappingTarget List<ChildTarget> result, List<ChildSource> source ) {
// write whatever merge functionality you desire and call 'merge' for the ChildTarget / ChildSource here
}
void merge(@MappingTarget ChildTarget result, ChildSource request);
}
我有两种合并方法,一种用于父对象,一种用于子对象
@Mappings({
@Mapping(target="childs", source="childs")
})
void merge(@MappingTarget Target result, Source request);
void merge(@MappingTarget ChildTarget result, ChildSource request);
现在MapStruct生成第一个合并方法的实现如下
@Override
public void merge(Target result, Source request) {
if ( request == null ) {
return;
}
if ( result.getChilds() != null ) {
// I want to instruct MapStruct to call merge for Child object
List<ChildTarget> list = childSourceListToChildTargetList( request.getChilds() );
if ( list != null ) {
result.getChilds().clear();
result.getChilds().addAll( list );
}
else {
result.setChilds( null );
}
}
else {
List<ChildTarget> list = childSourceListToChildTargetList( request.getChilds() );
if ( list != null ) {
result.setChilds( list );
}
}
}
protected List<ChildTarget> childSourceListToChildTargetList(List<ChildSource> list) {
if ( list == null ) {
return null;
}
List<ChildTarget> list1 = new ArrayList<ChildTarget>( list.size() );
for ( ChildSource childSource : list ) {
list1.add( childSourceToChildTarget( childSource ) );
}
return list1;
}
我尝试了各种注释,但无法找到任何确切的解决方案
如果我理解正确你正在尝试做什么,一种可能的解决方案是使用 expressions:
@Mappings({
@Mapping(target="childs",
expression = "java( mergeChilds(target, request) )")
})
void merge(@MappingTarget Target result, Source request);
请注意 mergeChilds
必须具有以下签名:
List<ChildTarget> mergeChilds(Target target, Source source)
例如,它可以是您界面中的一个 default
方法,并且必须包含您的域特定逻辑来处理合并。
MapStruct 无法正确执行此操作。查看 here 原因。如何合并集合与用例密切相关(正如您已经发现的那样)。
但是你总是可以自己做,MapStruct 会select那个方法。
@Mapping(target="childs", source="childs") // you can omit @Mappings in java8
void merge(@MappingTarget Target result, Source request);
default void merge(@MappingTarget List<ChildTarget> result, List<ChildSource> source ) {
// write whatever merge functionality you desire and call 'merge' for the ChildTarget / ChildSource here
}
void merge(@MappingTarget ChildTarget result, ChildSource request);
}