我试图有条件地使用一个吸气剂或另一个,取决于 Map 的根/源的条件 . A
引用 B
;但是,它(引用)被允许为null . 当引用不为null时,我想使用它的一个属性( B
) . 但是,当引用为null时,我想使用源中的属性( A
) .
它's a little business-logic' y但是我们的系统中有很多数据模型遵循这种模式 . 它'd be beneficial to use a mapper library and in my mind the logic is simple enough - it'与使用库的 Condition
非常相似 .
当我在getter中使用逻辑时,它将启动并初始化正常;但是,当 Map 实际用于映射对象时,我从Model-Mapper获得 IllegalArgumentException
,其中包含 object is not an instance of declaring class
.
我没有解决问题的方法 . 它似乎更像是一次性完成,而不是if-or-else . 我有一个映射器,它首先在源上使用getter( A
) . 在下一行,我然后调用条件 Conditions.isNotNull())
并映射 a -> a.getB().getDescription()
. 所以在我看来它是如何工作的首先是使用 A
设置DTO的 description
属性 . 然后它将"overwrite"与 a.getB().getDescription()
的值,但仅当 a.getB()
不为空时 . 但是,它似乎没有那样工作 . 相反,对于 a.getB()
返回null的实例,我将 null
视为DTO的 description
.
总之,我希望能够做类似以下的事情:
modelMapper.createTypeMap(A.class, FlatAB.class).addMappings(mapper -> {
mapper.map(a -> a.getB() != null ? a.getB().getDescription() :
a.getDescription(), FlatAB::setDescription);
});
这里有一些示例代码来演示我面临的问题 .
import java.util.Optional;
import org.junit.Assert;
import org.junit.Test;
import org.modelmapper.ModelMapper;
public class TestMappingConditionalGettersWithModelMapper {
@Test
public void testConditionalGetter() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.createTypeMap(A.class, FlatAB.class).addMappings(mapper -> {
// mapper.map(a -> a.getB() != null ? a.getB().getDescription() : a.getDescription(), FlatAB::setDescription);
mapper.map(a -> Optional
.ofNullable(a.getB())
.map(B::getDescription)
.orElseGet(a::getDescription), FlatAB::setDescription);
});
// first try A with no relationship
A a = new A();
a.setDescription("description of A");
FlatAB flatAB1 = modelMapper.map(a, FlatAB.class);
Assert.assertEquals("they should equal", a.getDescription(), flatAB1.getDescription());
// now try it WITH a relationship
A a2 = new A();
a2.setDescription("description of A2");
B b = new B();
b.setDescription("description of B");
a2.setB(b);
FlatAB flatAB2 = modelMapper.map(a2, FlatAB.class);
Assert.assertEquals("they should equal", b.getDescription(), flatAB2.getDescription());
}
}
class A {
private String description;
private B b;
/*
.....
.....
many other properties
.....
....
*/
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
class B {
private String description;
/*
.....
.....
many other properties
.....
....
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
2 回答
I popped the question over on the library's Github并得到了维护者的极好回答,Chun-Han, Hsiao .
我发现
ctx.getSource()
可能需要施法 - 但我是一种喂养这种类型的方法 .如果我正确地理解了你的问题,我会像他一样
如果b不为空,这将产生B描述,否则为A描述 .
UPDATE
将上面的代码放到单独的方法中就可以了解A.getMappingDescription(),如:
您的映射将更简单:
更新2
您可以简单地提取指定具体泛型类型的转换器,如:
或明确表示: