От плоской модели Java ModelMapper к иерархической модели

Я использую www.modelmapper.org и работаю над отображением одного и того же "плоского" Java DTO в несколько "иерархических "DTO.
" Плоский "DTO имеет ряд примитивных свойств.
" Иерархический "имеет ряд сложных типов, которые содержат ряд примитивных типов. Эти DTO очень похожи, но не одинаковы.

"Плоский" DTO:

class TransactionRequest
{
    String cashierNumber;
    Long amount;
    Integer currency;

    public String getCashierNumber {..
    ...
}

"Иерархические DTO:

class PurchaseRequest
{
    POSInfo posInfo;
    Amount amount;        
    ...    

    public PosInfo getPosInfo {..
    public Amount getAmount { ..
    ...
}

class CancelRequest
{
    POSInfo posInfo;
    Amount amount;        
    ...

    public PosInfo getPosInfo {..
    public Amount getAmount { ..
    ...
}

class Amount
{    
    BigDecimal value;
    Integer currency;

    public Integer getCurrency{..
    ...
}

class PosInfo
{    
    String cashierNumber;

    public String getCashierNumber {..
}

TransactionRequest должен отображаться в 1) PurchaseRequest и 2) CancelRequest.
Одна из проблем заключается в том, что сумма должна быть преобразована из Long (в второстепенных единицах) в BigDecimal (в основных единицах с десятичными цифрами). Я добился этого, написав свой собственный конвертер Long to BigDecimal. Теперь у меня есть проблема определить отображения, необходимые для многократного использования. Чего я не хочу, так это определять сопоставления для каждого целевого типа следующим образом:

class PurchaseMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}

class CancelMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}

Я хотел бы только один раз определить сопоставление Amount DTO (и всех других сопоставлений подтипов, таких как PosInfo и многие другие), а затем повторно использовать эти сопоставления. Я попробовал несколько вариантов:

Первое, что я попробовал, - это объявить отображение TransactionRequest на Amount DTO в моем ModelMapper. Во-первых, я предположил, что простого объявления этого сопоставления будет достаточно, чтобы механизм сопоставления также был задействован при сопоставлении TransactionRequest с PurchaseRequest. Однако это не так.

Второе, что я попробовал, работает, но кажется слишком сложным:

  1. Я создал PropertyMap для сопоставления TransactionRequest с Amount.
  2. Я создал собственный конвертер TransactionRequest в Amount. Конструктору этого конвертера требуется ModelMapper. ModelMapper, который я передаю конструктору, - это ModelMapper, который создал PropertyMap из 1)
  3. Я использую этот конвертер в PropertyMaps для PurchaseRequest и CancelRequest.

Вот код:

public class AmountMap extends PropertyMap<TransactionRequest , Amount>
{
    ....

    protected void configure()
    {
      using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
        }
       ...
    }
}

public class TransactionRequestToAmountConverter extends AbstractConverter<TransactionRequest, Amount>
{
    private final ModelMapper mapper;

    public TransactionRequestToAmountConverter(ModelMapper mapper)
    {
        this.mapper = mapper;
    }

    public Amount convert(TransactionRequest transactionRequest)
    {
        return mapper.map(transactionRequest, Amount.class);
    }
}

public class PurchaseRequestMap extends PropertyMap<TransactionRequest, PurchaseRequest>
{
    private final ModelMapper   mapper;

    public PurchaseRequestMap(ModelMapper mapper)
    {
        this.mapper = mapper;
    }

    protected void configure()
    {           
        using(new TransactionRequestToAmountConverter(mapper)).map(source).setAmount(null);
        ...

    }
}

Есть ли кто-нибудь, кто знает более простой подход к этому?


person Martin    schedule 12.01.2015    source источник


Ответы (1)


Попробуйте сопоставить Long с Amount самостоятельно:

modelMapper.createTypeMap(Long.class, Amount.class).setConverter(new Converter<Long, Amount>() {
  //... convert Long to Amount
});

Затем это сопоставление будет использоваться в других ваших типах и должно устранить необходимость в других вещах (если я правильно читаю ваши типы).

person Jonathan    schedule 13.01.2015