Mapstruct:如何使用相同的映射器将A扩展SingleValue <t>到T,将A扩展SingleValue <t>到B扩展SingleValue <t>?

时间:2019-02-22 15:32:35

标签: java generics mapstruct

我已经盯着这个问题已经有一段时间了,一直找不到答案。我正在尝试使用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>{

}

并且将在可能相互映射的不同对象中使用

可能的映射:

  • 字符串->名字
  • 名字->字符串
  • FirstName->另一个扩展SingleValue对象

当前解决方案可以进行以下映射:

  • 字符串->名字
  • 名字->字符串

当前单值映射器

@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);
}

上述映射方法存在的问题:

  • 在自动选择中,Mapstruct将首选getValue(Z singleValue)映射而不是此映射(我真的不想使用限定符,因为那样的话我需要限定im映射的每个字段)
  • 如果例如我们还为UUID单值添加一个,则Mapstruct将认为映射方法不明确

在将字符串映射到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-最终版。

0 个答案:

没有答案