Reputation: 371
I'm trying to serialize an object which contains a HashMap and i get following exception.
com.fasterxml.jackson.dataformat.csv.CsvMappingException: Unrecognized column 'tags': known columns: ["_id","insertDate"] (through reference chain.
Also, I don't understand why it's necessary to have a schema when it's about serialization. In my mind, there is no way to have an unrecognized field because all it's specified inside the class.
Because i don't know well Jackson, i searched and tried various combination of these 2 annotations. @JsonUnwrapped
@JsonAnyGetter
class Product{
public @Id String _id;
@JsonUnwrapped
private HashMap<String, String> tags = new HashMap<>();
public String insertDate;
@JsonAnyGetter
public HashMap<String, String> getTags() {
return tags;
}
@JsonAnySetter
public void setTags(HashMap<String, String> tags) {
this.tags = tags;
}
}
Code used for serialization
CsvSchema schema = csvMapper.schemaFor(Product.class).withHeader();
ObjectWriter myObjectWriter = csvMapper.writer(schema);
csvMapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE);
csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
string = myObjectWriter.writeValueAsString(someProduct);
TRY NR 2
public class Product {
public @Id String _id;
public Map<String, String> tags = new HashMap<>();
public String insertDate;
@JsonAnyGetter
public Map<String, String> getTags() {
return tags;
}
@JsonAnySetter
public void setTags(Map<String, String> tags) {
this.tags = tags;
}
}
NEW ERROR
com.fasterxml.jackson.dataformat.csv.CsvMappingException: CSV generator does not support Object values for properties (nested Objects) (through reference chain: main.model.Product["tags"])
Upvotes: 1
Views: 2611
Reputation: 114
Using Collection
implementation class HashMap<String, String>
for field type (rather than only for its initial value type) confuses Jackson.
Jackson checks for interface java.util.Map
to choose proper Serializer, as evidenced in constructor of
com.fasterxml.jackson.databind.ser.std.MapSerializer
As per Schema question, according to jackson-dataformat-csv docs
It is important to note that the schema object is needed to ensure correct ordering of columns;
Note also that while explicit type can help efficiency it is usually not required, as Jackson data binding can do common conversions/coercions
I guess ObjectWriter.writeValueAsString(Object)
could check reflexively to infer type for serialized object.
Due to tabular nature of CSV format, deeply nested data structures are not well supported.
@JsonUnwrapped
is for (nested) POJO-s only. What you want is to use @JsonAnyGetter
. And it needs to return java.util.Map
. JavaDocs:
Note that the return type of annotated methods must be Map).
If you are only serializing, @JsonAnySetter
won't be needed.
I'm curious why are you using Map for tags. Maybe List<String> tags
would suffice, tags have only names.
Worth checking out: https://www.baeldung.com/jackson-mapping-dynamic-object
Upvotes: 1