英文:
Specify the name of the object that will be used for implicit mapping by MapStruct
问题
@Mapping(target = "ca1", source = "a.ca1")
@Mapping(target = "ca2", source = "a.ca2")
C mapFrom(A a, B b);
我想要在MapStruct中明确指定哪个对象将用于参数中传递的对象进行隐式映射,我有以下示例:
@Mapping(target = "ca1", source = "a.ca1")
@Mapping(target = "ca2", source = "a.ca2")
C mapFrom(A a, B b);
我想要使用A进行显式映射,B用于所有隐式映射,问题是A和B具有许多具有相同名称的属性,它们之间会发生冲突。我尝试使用
@Mapping(target = ".", source = "b")
但这并不能解决问题,我仍然收到"java: Several possible source properties for target property..."错误。另外,使用`@BeanMapping(ignoreByDefault = true)` 将会很困难,因为我将不得不手动编写很多映射。如果我们能够指定用于隐式映射的对象将非常方便,有什么帮助吗?(我正在使用版本1.5.2)
<details>
<summary>英文:</summary>
I would like to know if it's possible in MapStruct to specify explicitly what is the object that will be used for implicit mapping among the ones passed in argument to the mapper, I have the following example :
@Mapping(target = "ca1", source = "a.ca1")
@Mapping(target = "ca2", source = "a.ca2")
C mapFrom(A a, B b);
I want to use A for explicit mapping and B for all implicit mapping, the issue is that A and B have a lot of properties with same name that conflicts together, I tried to use
@Mapping(target = ".", source = "b")
but that does not solve the issue, I still get java: Several possible source properties for target property... Error, also using the ```@BeanMapping(ignoreByDefault = true)``` will make it very difficult as I will have to wirte by hand a lot of mappings. I think it will be very handy if we could specify the object that will be used for implicit mapping, any help ? (I am using version 1.5.2)
</details>
# 答案1
**得分**: 1
根据[MapStruct文档][1]的说明:
> 如果多个源对象定义具有相同名称的属性,则必须使用@Mapping注释指定要检索属性的源参数,如示例中所示的描述属性。如果不解决此类模糊性,则将引发错误。
但是,可以通过以下3种方法的下一个解决方案来实现所需的功能:
```java
@Mapper
public interface TestMapper {
TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);
default ResultClass combineOrdered(ImplicitClass implicitClass, ExplicitClass explicitClass) {
ResultClass resultClass = populateImplicitly(implicitClass);
populateExplicitly(resultClass, explicitClass);
return resultClass;
}
ResultClass populateImplicitly(ImplicitClass implicitClass);
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "explicitClass.explicitField", target = "explicitField")
void populateExplicitly(@MappingTarget ResultClass resultClass, ExplicitClass explicitClass);
}
MapStruct将生成populateImplicitly
方法的代码,从ImplicitClass中隐式填充所有字段,以及populateExplicitly
方法的代码,仅显式填充来自ExplicitClass的声明字段。
这两种方法可以使用额外的combineOrdered
方法组合在一起,首先调用隐式映射(以填充所有字段),然后只填充显式字段。
使用combineOrdered
方法应该有助于实现您所需的功能。
英文:
According to MapStruct documentation:
> In case several source objects define a property with the same name,
> the source parameter from which to retrieve the property must be
> specified using the @Mapping annotation as shown for the description
> property in the example. An error will be raised when such an
> ambiguity is not resolved.
However, needed functionality could be achieved with a next workaround of 3 methods:
@Mapper
public interface TestMapper {
TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);
default ResultClass combineOrdered(ImplicitClass implicitClass, ExplicitClass explicitClass) {
ResultClass resultClass = populateImplicitly(implicitClass);
populateExplicitly(resultClass, explicitClass);
return resultClass;
}
ResultClass populateImplicitly(ImplicitClass implicitClass);
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "explicitClass.explicitField", target = "explicitField")
void populateExplicitly(@MappingTarget ResultClass resultClass, ExplicitClass explicitClass);
}
MapStruct will generate code for populateImplicitly
method to implicitly populate all fields from ImplicitClass - and code for populateExplicitly
method to explicitly populate only declared fields from ExplicitClass.
And those 2 approaches could be combined using additional method combineOrdered
- which will first call implicit mappings (to populate all the fields) - and then will populate only explicit fields.
Usage of such combineOrdered
method should help to do what you're looking for.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论