1

I have following classes:

@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public abstract class Parent {
    private String parentA;
    private String parentB;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class ChildOne extends Parent{
    private String childOneA;
    private String childOneB;
}
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class ChildTwo extends Parent{
}
Map<Parent, List<String>> parent2Strs = new HashMap<>();
parent2Strs.put(ChildTwo.builder().parentA("A").parentB("B").build(), List.of("1", "2"));
parent2Strs.put(ChildTwo.builder().parentA("C").parentB("D").build(), List.of("1"));

When I call writeValueAsString() method on the parent2Str class, it doesn't print any attribute in parent class.

I tried to use @Jacksonized on the abstract class. But received error:

error: Builders on abstract classes cannot be @Jacksonized (the builder would never be used).

How can I include the fields in Parent class when serialize the child class?

EzyHoo
  • 301
  • 2
  • 14
  • 1
    Your `ChildOne`/`ChildTwo` classes don't `extend Parent`. Is that a typo? Otherwise it's obvious why it doesn't work. – Jan Rieke Apr 09 '23 at 15:27
  • @JanRieke. Thx. It is a typo. Fixed – EzyHoo Apr 10 '23 at 20:44
  • 1
    That works for me, all attributes from child and parent are serialized. Please add more code so we can see exactly how you create the instance and serialize it. – Jan Rieke Apr 12 '23 at 08:16
  • @JanRieke Thank you for checking. I also tested. Looks like when printing the individual Child object, it will show the attributes from parent class. But when printing the child in a map, it doesn't show any attribute from parent class. Update the description. – EzyHoo Apr 18 '23 at 04:13
  • Your updated code does not compile, and it's also not clear what you mean by "when printing the child in a map". Please add exactly the code that causes the problem. – Jan Rieke Apr 27 '23 at 11:56
  • @JanRieke Thx for checking. My apology. Update the code. I was trying to say that when writeValueAsString() each Child Object in a Child Object List, it does show all the attribute for each class. But when writeValueAsString() the whole Map. The ChildTwo object doesn't have any attribute. Hope I explained my problem clearly this time – EzyHoo May 01 '23 at 22:52

1 Answers1

1

This behavior has nothing to do with Lombok, @SuperBuilder, or @Jacksonized. Jackson simply serializes map keys using the toString() method, because keys in JSON cannot be structured, but must be plain strings.

If you use your POJOs as map values, everything works as expected (and would also work without @SuperBuilder).

@Jacksonized wouldn't have an effect anyway, because it only affects the deserialization, not the serialization.

Jan Rieke
  • 7,027
  • 2
  • 20
  • 30
  • Thx. Sounds like a limitation of Java Map? So is there a way to print out the parent2Strs keys including the parent fields? – EzyHoo May 08 '23 at 04:55
  • That's not a limitation of Java Maps. It's just the definition of JSON: JSON keys must be strings. You can still change the `toString` method, e.g. by adding `@ToString(callSuper=true)` to your classes. – Jan Rieke May 08 '23 at 06:04