9

I am trying to read a CSV file with certain headers into a Java object using Apache Commons CSV. However, when I run the code, I get the following exeption:

Exception in thread "main" java.lang.IllegalArgumentException: Mapping for Color not found, expected one of [Color, Name, Price, House Cost, Rent, 1 House, 2 Houses, 3 Houses, 4 Houses, Hotel, Mortgage]
at org.apache.commons.csv.CSVRecord.get(CSVRecord.java:102)
at GameBoard.<init>(GameBoard.java:25)
at Game.main(Game.java:3)

Can someone explain where the exception is coming from? It appears to me that Apache Commons somehow is not matching my input to a column. Is there something wrong on my part or is something else broken? Here is my code snippet:

Reader in;
    Iterable<CSVRecord> records = null;
    try {
        in = new FileReader(new File(Objects.requireNonNull(getClass().getClassLoader().getResource("Properties.csv")).getFile()));
        records = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(in);
    } catch (IOException | NullPointerException e) {
        e.printStackTrace();
        System.exit(1);
    }
    for (CSVRecord record :
            records) {
        spaces.add(new Property(
                record.get("Color"),
                record.get("Name"),
                Integer.parseInt(record.get("Price")),

And here are my csv headers (sorry, one was cut off but that's not the point): csv headers

Thanks!

Norman Percy
  • 858
  • 1
  • 8
  • 13
  • I am wondering if it might be related to this issue: https://stackoverflow.com/questions/10277348/how-does-get-work-on-hashmap but if so, I cannot figure out how to get around it. – Norman Percy Dec 06 '18 at 02:06
  • Looks like a strange mismatch, it does not match a header while that header is in the list. Maybe some special characters or trailing whitespaces in the CSV-file, can you show how the csv file looks as text, i.e. the contents of the csv file. – centic Dec 08 '18 at 11:10

4 Answers4

8

I had the same probem which only occurs if you reference the first column, all other column names are working. The problem is, that the UTF-8 representation prepends the following characters "0xEF,0xBB,0xBF" (see Wikipedia page). This seems to be a known problem for commons-csv but since this is application specific, it won't be fixed (CSVFormat.EXCEL.parse should handle byte order marks).

However, there is a documented workaround for this:

http://commons.apache.org/proper/commons-csv/user-guide.html#Handling_Byte_Order_Marks

Thorsten Kitz
  • 165
  • 2
  • 7
  • 1
    This should be marked as accepted. Note that in the question, the issue is with the first column as well. – RyanQuey Sep 10 '20 at 19:42
2

Moving to spring boot version 2.6.7 from 2.4.5 brought about this error.. I had to convert each csvRecord to a map before assigning it to my POJO as follows.

for (CSVRecord csvRecord : csvRecords) {

            Map<String, String> csvMap = csvRecord.toMap();

            Model newModel = new Model();
           model.setSomething(csvMap.get("your_item"));
        }
0

I got the same weird exception. It actually said "Expecting one of ..." and then listed the field it said it could not find - just like in your case.

The reason was that I had set the wrong CSVFormat:

CSVFormat csvFormat = CSVFormat.newFormat(';');

This meant that my code was trying to separate fields on semi-colons in a file that actually had comma separators.

Once I used the DEFAULT CSVFormat, everything started to work.

CSVFormat csvFormat = CSVFormat.DEFAULT;

So the answer is that probably you must set CSVFormat correctly for your file.

mwarren
  • 2,409
  • 1
  • 22
  • 28
-1

enter image description here

I also got the same exception by giving a different name of header in CSV file like xyz, or trying to get the value by calling csvRecord.get("x_z")

I resolved my problem changing the header name xyz.

try {
  fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  csvParser = new CSVParser(fileReader,
      CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());
  Iterable<CSVRecord> csvRecords = csvParser.getRecords();
  CSVFormat csvFormat = CSVFormat.DEFAULT;
  for (CSVRecord csvRecord : csvRecords) {


} catch (Exception e) {
  System.out.println("Reading CSV Error!");
  e.printStackTrace();
} finally {
  try {
    fileReader.close();
    csvParser.close();
  } catch (IOException e) {
    System.out.println("Closing fileReader/csvParser Error!");
    e.printStackTrace();
  }
}
Pawel Veselov
  • 3,996
  • 7
  • 44
  • 62