Reputation: 3064
I have a csv file that contains no header column(s). Each row contains a row type in it's first column and the row type will determine which columns the row will have. Here is a simplified version:
"TypeARow","20240210"
"TypeBRow","5610429110","test"
I am trying to parse this using jackson-dataformat-csv
and polymorphism. My test code looks like this:
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvParser;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
public class JacksonTest {
@Test
void testParsing() throws IOException {
var mapper = new CsvMapper()
.enable(CsvParser.Feature.WRAP_AS_ARRAY);
var file = new File("sample.csv");
var schema = CsvSchema.emptySchema().withoutHeader();
try (var it = mapper.readerFor(CustomRow.class).with(schema).readValues(file)) {
while (it.hasNext()) {
Object row = it.next();
System.out.println(row);
}
}
}
}
I have modeled the row types like this:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = TypeARow.class, name = "TypeARow"),
@JsonSubTypes.Type(value = TypeBRow.class, name = "TypeBRow"),
// Add more subtypes if needed
})
public interface CustomRow {
String getType();
}
@JsonDeserialize(as = TypeARow.class)
class TypeARow implements CustomRow {
private final String type;
private final String column1;
public TypeARow(String column1) {
this.type = "TypeARow";
this.column1 = column1;
}
@Override
public String getType() {
return type;
}
}
@JsonDeserialize(as = TypeBRow.class)
class TypeBRow implements CustomRow {
private final String type;
private final String column1;
private String column2;
public TypeBRow(String column1, String column2) {
this.type = "TypeBRow";
this.column1 = column1;
this.column2 = column2;
}
@Override
public String getType() {
return type;
}
}
The error I am currently seeing is:
com.fasterxml.jackson.databind.RuntimeJsonMappingException: Cannot construct instance of `com.package.TypeBRow` (no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('5610429110')
at [Source: (FileInputStream); line: 2, column: 12]
indicating that it fail to create the TypeBRow
by calling the constructor with 2 elements. Any ideas?
Upvotes: 0
Views: 84