我已经盯着这个问题已经有一段时间了,一直找不到答案。我正在尝试使用mapstruct映射具有字段的对象,这些字段是通用SingleValue对象的实现。
让我用一个简化的例子来说明这个问题。 (出于可读性考虑,将其省略)
我们有一个单一值对象:
public abstract class SingleValue<T extends Serializable> implements Serializable {
private T value;
public SingleValue(T value) {
this.value = value;
}
}
具体的Single value类看起来像这样
public class FirstName extends SingleValue<String>{
}
并且将在可能相互映射的不同对象中使用
可能的映射:
当前解决方案可以进行以下映射:
当前单值映射器
@Mapper
public interface SingleValueMapper {
SingleValueMapper INSTANCE = Mappers.getMapper(SingleValueMapper.class);
default <Z extends Serializable, T extends SingleValue<Z>> T singleValue(Z obj, Class<Z> objClass, @TargetType Class<T> targetType) {
if (obj == null) {
return null;
}
return targetType.getConstructor(objClass).newInstance(obj);
}
default <T extends Serializable, Z extends SingleValue<T>> T getValue(Z singleValue) {
if (singleValue == null) {
return null;
}
return singleValue.getValue();
}
default <T extends SingleValue<String>> T singleValue(String obj, @TargetType Class<T> targetType) {
return singleValue(obj, String.class, targetType);
}
}
对于名字->另一个扩展的SingleValue对象映射,我想出了以下无效的解决方案:
default <T extends SingleValue<String>> T stringSingleValue(SingleValue<String> obj, @TargetType Class<T> targetType)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
return singleValue(obj.getValue(), String.class, targetType);
}
上述映射方法存在的问题:
在将字符串映射到A扩展SingleValue时,此调用是由mapstruct生成的:
A a = singleValueMapper.singleValue( client.getCompanyName(), A.class )
mapstruct不会选择此调用,但是当以@Mapping作为表达式手动使用它时,我们可以使用它。但是,我们希望mapstruct在映射A扩展SingleValue到B扩展SingleValue时自动映射这些调用:
B b =singleValueMapper.stringSingleValue(command.getTitle(), B.class)
有没有办法通过mapstruct和Java泛型实现这一目标?
我正在使用Mapstruct 1.3.0-最终版。