Hello,
version 1.52 of SuperCSV exhibits a very similar error to the one described in bug number 2093734. When using an Optional cellprocessor with for example a ParseDate cellprocessor, CsvBeanReader will throw a NullPointerException during the execution of fillObject(...).
The error is in line 72, that reads:
cache.getSetMethod(resultBean, nameMapping[i], lineResult.get(i).getClass())//
.invoke(resultBean, lineResult.get(i));
lineResult.get(i) will be null if Optional found an empty string. The CsvBeanReader should not invoke a setter if the value to be set is null. Following code will fix that:
if (lineResult.get(i) != null) {
cache.getSetMethod(resultBean, nameMapping[i], lineResult.get(i).getClass())//
.invoke(resultBean, lineResult.get(i));
}
Thank you very much for putting so much effort into SuperCSV.
Cheers,
Nico
Hi Nico
thanks for the report. I'm looking at it now. I'm not 100% convinced about your solution, as it will prevent e.g. the "Optional" or the "ConvertNullTo" processors from ever executing on nulls... maybe those two processors should implement some empty interface that denotes the processor should be invoked even on empty input. this makes the cellprocessor architecture a bit more complicated, but i don't see it as a big deal. Then instead of checking if the input is != null, it must also check the first processor as it may be able to handle the null input and return something the setter method can set..e.g. a default date in your example.
What do you (and others) think of such a solution?
many thanks
kasper
Hi Kasper,
you are right. My initial fix is too narrowminded, because it will only resolve my problem at hand but break other things. I'm not too familiar with the SuperCSV architecture, but what you are saying seems to make sense. I don't know if your solution with an empty interface will result in a good solution, since I haven't looked at the SuperCSV code except the CsvBeanReader.
Greetings,
Nico
Try this one:
cache.getSetMethod(resultBean, nameMapping[i],
lineResult.get(i) == null ? null : lineResult.get(i).getClass())//
.invoke(resultBean, lineResult.get(i));
Fix ASAP.
I stumbled upon the same problem in the same (latest) version, when parsing empty CSV columns.
My fix in method fillObject() below:
Object lineVal = lineResult.get(i);
Class<?> lineClazz = lineVal != null ? lineVal.getClass() : null;
I realize there hasn't been any discussion on this for 2 years - but it's still an issue.
To fix this, I just modified CsvBeanReader class' fillObject method to ignore lineResults that are null (all the other solutions provided execute unnecessary lines of code, i.e. calling the methodCache).
The current comment regarding 'no result to store' is misleading, it should read 'no mapping'. 'No result to store' is actually when the lineResult is null (the last executing processor returned null).
Kasper, I think you're making things complicated! This has no impact on the CellProcessors at all. The 'Optional' and 'ConvertNullTo' processors (and every other processor) execute before the fillObject method does. It just means that if the end result of the processor chain is null, then the setter for that column value will not be executed so the field will keep its default value (null for objects, primitive defaults for primitives).
This bug still exists, and it's a very easy fix. In one line:
Here's a link to the fix in patch format:
https://gist.github.com/806933
jamesbassett's assessment from 10 months ago is correct. Please commit the change.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
The author already applied the bugfix to his svn. There you can create a SuperCSV 1.53
Last edit: Anonymous 2014-09-08
This fix will be available in the upcoming release!