-1

My problem is that I have got a dto called PhoneBillPaymentDTO which has a field phoneNumber annotated with @NotNull. When I map this dto that has null phone number with ModelMapper to PhoneBillPayment Entity, it does not throw exception.

How can I make it throw exception when a notnull value is set as null ?

Here my classes are;

public class PhoneBillPaymentTransactionDTO extends PaymentTransactionDTO {

    @NotNull
    private String phoneNumber;

    public PhoneBillPaymentTransactionDTO() {

    }

    public PhoneBillPaymentTransactionDTO(@NotNull BigDecimal amount, @NotNull TransactionTypes type,
            @NotNull String payeeAccountNumber, @NotNull String owner, @NotNull String phoneNumber) {
        super(amount, type, payeeAccountNumber, owner);
        this.phoneNumber = phoneNumber;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

}

Controller:

@PostMapping(path = "/payment/{accountNumber}")
public ResponseEntity<TransactionStatus> payment(@PathVariable String accountNumber,
        @Valid @RequestBody PaymentTransactionDTO paymentTransactionDTO) throws InsufficientBalanceException {

    return new ResponseEntity<>(
            accountService.payment(accountNumber, MapperUtil.createTrxByTrxDTO(paymentTransactionDTO)),
            HttpStatus.OK);
}

Mapper Util:

public final class MapperUtil {

    private MapperUtil() {

    }

    private static final ModelMapper mapper = new ModelMapper();

    public static final Transaction createTrxByTrxDTO(TransactionDTO dto) {
        if (dto.getType() == TransactionTypes.DEPOSIT) {
            return mapper.map(dto, DepositTransaction.class);
        }
        if (dto.getType() == TransactionTypes.WITHDRAWAL) {
            return mapper.map(dto, WithdrawalTransaction.class);
        }
        if (dto.getType() == TransactionTypes.PAYMENT) {
            return mapper.map(dto, PaymentTransaction.class);
        }
        if (dto.getType() == TransactionTypes.PHONEBILLPAYMENT) {
            mapper.getConfiguration().setPropertyCondition(Conditions.isNotNull());
            return mapper.map(dto, PhoneBillPaymentTransaction.class);
        }
        throw new UnsupportedTransactionTypeException();
    }


}
HiIamAnil
  • 11
  • 3

1 Answers1

0

First: I am pretty sure that ModelMapper does not do JSR-303 annotation validation out of the box. You would need to use programmatic validator for the resulting bean.

But the bigger problem in your approach is:

In your controller you expect PaymentTransactionDTO. That might be validated by Spring but because Spring has no knowledge about that it might actually be PhoneBillPaymentTransactionDTO and therefore phoneNumber - for example - should be validated it just is not done.

Now, if you test this more and log what Spring (or Jackson) deserializes out of your input that - again - is PaymentTransactionDTO for controller method, can it ever have phoneNumber? I bet you have configured somewhere DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES = false to have this even working this far.

pirho
  • 11,565
  • 12
  • 43
  • 70