6

I want to map to a source destination which only have a constructor that takes 3 parameters. I get the following error:

Failed to instantiate instance of destination com.novasol.bookingflow.api.entities.order.Rate. Ensure that com.novasol.bookingflow.api.entities.order.Rate has a non-private no-argument constructor.

It works when I insert a no-args constructor in the source destination, but that can lead to misuse of the class, so I would rather not o that.

I have tried using a Converter, but that does not seem to work:

Converter<RateDTO, Rate> rateConverter = new AbstractConverter<RateDTO, Rate>() {
    protected Rate convert(RateDTO source) {
        CurrencyAndAmount price = new CurrencyAndAmount(source.getPrice().getCurrencyCode(), source.getPrice().getAmount());
        Rate rate = new Rate(price, source.getPaymentDate(), source.getPaymentId());
        return rate;
    }
};

Is it possible to tell modelmapper how to map to a destination with a no no-args constructor?

Lars Rosenqvist
  • 421
  • 7
  • 17
  • You can also use a [Provider](http://modelmapper.org/user-manual/providers/) to instantiate your destination class. – Jonathan Sep 01 '16 at 16:03
  • Hi Jonathan, yes that is what I ended up doing, see my own answer. – Lars Rosenqvist Sep 02 '16 at 05:52
  • @Lars: I ran into the same problem as you but then tried out a private no-args ctor (even though the message says otherwise). ModelMapper is capable of reading a private ctor (v0.7.6) and as such you are still protected against unwanted instantiation/use of your class. In fact, by proactively placing a private no-args ctor you can (specifically through commenting) make your peers aware that you designed this class to not expose a no-args ctor. – Cerbenus Jan 19 '17 at 19:31

1 Answers1

8

This seemed to do the trick:

    TypeMap<RateDTO, Rate> rateDTORateTypeMap = modelMapper.getTypeMap(RateDTO.class, Rate.class);
    if(rateDTORateTypeMap == null) {
        rateDTORateTypeMap = modelMapper.createTypeMap(RateDTO.class, Rate.class);
    }
    rateDTORateTypeMap.setProvider(request -> {
        RateDTO source = RateDTO.class.cast(request.getSource());
        CurrencyAndAmount price = new CurrencyAndAmount(source.getPrice().getCurrencyCode(), source.getPrice().getAmount());
        return new Rate(price, source.getPaymentDate(), source.getPaymentId());
    });
Lars Rosenqvist
  • 421
  • 7
  • 17