1
0

Part 5: writeValueAsString(List) drops the discriminator - and the two fixes

This commit is contained in:
2026-08-04 17:32:36 +00:00
parent 5c6e87bea2
commit fc99bd34a9

View File

@@ -0,0 +1,60 @@
package com.ankurm.jackson3.part5polymorphic;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.json.JsonMapper;
import java.util.List;
/**
* Post: Polymorphic Deserialisation — https://ankurm.com/jackson-polymorphic-deserialization/
* Section: "Serialising a Mixed List"
*
* CORRECTION TO THE POST. The post shows
*
* mapper.writerWithDefaultPrettyPrinter().writeValueAsString(payments)
*
* producing JSON that contains "paymentType". It does not. Passing a List to
* writeValueAsString gives Jackson only the runtime class (ImmutableCollections.ListN),
* which carries no element type, so the polymorphic type serialiser is never engaged
* and the discriminator is silently omitted. The resulting JSON then fails to
* deserialise — see F02DeserialiseMixedList.
*
* Two things do work: a typed array, or writerFor(TypeReference).
*/
public class F01SerialiseMixedList {
static List<PaymentMethod> samplePayments() {
CreditCardPayment card = new CreditCardPayment();
card.setPaymentId(1L);
card.setAmountDue(99.99);
card.setCardNumberLastFour("4242");
card.setCardNetwork("VISA");
BankTransferPayment bank = new BankTransferPayment();
bank.setPaymentId(2L);
bank.setAmountDue(250.00);
bank.setBankAccountIban("GB29NWBK60161331926819");
bank.setBankName("National Bank");
return List.of(card, bank);
}
public static void main(String[] args) {
JsonMapper mapper = JsonMapper.builder().build();
List<PaymentMethod> payments = samplePayments();
System.out.println("--- 1. single element: discriminator present ---");
System.out.println(mapper.writeValueAsString(payments.get(0)));
System.out.println("--- 2. BROKEN: writeValueAsString(List) drops paymentType ---");
System.out.println(mapper.writeValueAsString(payments));
System.out.println("--- 3. FIX A: writerFor(TypeReference) ---");
System.out.println(mapper.writerFor(new TypeReference<List<PaymentMethod>>() { })
.withDefaultPrettyPrinter()
.writeValueAsString(payments));
System.out.println("--- 4. FIX B: a typed array carries its component type ---");
System.out.println(mapper.writeValueAsString(payments.toArray(new PaymentMethod[0])));
}
}