我试图根据地图的根/源条件有条件地使用一个或另一个吸气剂。 A
引用了B
;但是,(引用)允许为空。当引用为 not null 时,我想使用其中的属性(B
)。但是,当引用为空时,我想使用来源(A
)中的属性。
这有点商业逻辑,但是我们的系统中有很多遵循这种模式的数据模型。使用映射器库将是有益的,在我看来,逻辑很简单-与使用库的Condition
非常相似。
当我在getter中使用逻辑时,它将启动并初始化正常;但是,当该映射实际用于映射对象时,我从Model-Mapper获得了IllegalArgumentException
的{{1}}。
我无法适当地将库的object is not an instance of declaring class
放入解决方案中。它似乎更像是一劳永逸,而不是一个if-or-else。我有一个映射器,该映射器首先在源(Condition
)上使用getter。然后,在下一行中,我调用条件A
并映射Conditions.isNotNull())
。因此,在我看来,它将首先使用a -> a.getB().getDescription()
设置DTO的description
属性。然后它将用A
“覆盖”该值,但前提是a.getB().getDescription()
不为空。但是,它似乎没有那样工作。相反,对于a.getB()
返回null的实例,我将a.getB()
视为DTO的null
。
总而言之,我希望能够执行以下操作:
description
这里有一些示例代码来演示我面临的问题。
modelMapper.createTypeMap(A.class, FlatAB.class).addMappings(mapper -> {
mapper.map(a -> a.getB() != null ? a.getB().getDescription() :
a.getDescription(), FlatAB::setDescription);
});
答案 0 :(得分:1)
I popped the question over on the library's Github,并得到了维护者Chun-Han, Hsiao的出色答复。
没有转换器,我们无法将多个源属性映射到目标。
请尝试:
modelMapper.addMappings(mapper ->
mapper.using(ctx -> ctx.getSource().getB() != null
? ctx.getSource().getB().getDescription()
: ctx.getSource().getDescription())
.map(src -> src, FlatAB::setDescription));
我发现ctx.getSource()
可能需要强制转换-但我敢肯定有一种方法可以填充类型。
答案 1 :(得分:0)
如果我正确理解了您的问题,我会像
Optional
.ofNullable(a.getB())
.map(B::getDescription)
.orElseGet(a::getDescription)
如果b不为null,则将生成B描述,否则将生成A描述。
更新
将上面的代码放到单独的方法中将完成A.getMappingDescription()这样的技巧:
class A {
String desc;
B b;
public String getMappingDescription() {
return Optional
.ofNullable(getB())
.map(B::getDesc)
.orElse(desc);
}
...
}
您的映射会更简单:
modelMapper.createTypeMap(A.class, FlatAB.class).addMapping(A::getMappingDescription, FlatAB::setDesc);
更新2
您可以简单地提取指定具体泛型的转换器,例如:
Converter<A, String> descriptionConverter = ctx -> ctx.getSource().getB() != null
? ctx.getSource().getB().getDesc()
: ctx.getSource().getDesc();
mapper.using(descriptionConverter).map(src -> src, FlatAB::setDesc);
或显式转换为:
((Converter<A, String>) ctx -> ctx.getSource().getB()..