7

I'm trying to write a CSV using openCSV 4.1, from a list of beans. However, whenever I run my programme, I get CsvBeanIntrospectionException, and then a NoSuchMethodException: Unknown property 'fieldx' on class 'class TestObject'

I have successfully used the reader counterpart to read a CSV to a list of beans.

Here's my code for the object 'TestObject':

import com.opencsv.bean.CsvBindByName;
import java.io.Serializable;

public class TestObject implements Serializable {
    @CsvBindByName
    int fieldx;
    @CsvBindByName
    int fieldy;
    public TestObject() {
    }
    public TestObject(int x, int y) {
        this.fieldx = x;
        this.fieldy = y;
    }

    public int getX() {
        return fieldx;
    }
    public int getY() {
        return fieldy;
    }
    public void setX(int x) {
        this.fieldx = x;
    }
    public void setY(int y) {
        this.fieldy = y;
    }
    @Override
    public String toString(){
        return "{" + fieldx + "," + fieldy + "}";
    }
}

And here's the rest.

  public class Project {
    public static void main(String[] args) {
        TestObject t1 = new TestObject(1,2);
        TestObject t2 = new TestObject(3,4);

        List<TestObject> testList = new ArrayList<>();
        testList.add(t1);
        testList.add(t2);

        Prep prep = new Prep();
        try {
            prep.writeCSV(testList);
        } catch (IOException | CsvDataTypeMismatchException | CsvRequiredFieldEmptyException ex) {
            ex.printStackTrace();
        }
    }
}

import com.opencsv.bean.*;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;

public class Prep {
    public void writeCSV(List<TestObject> t) throws IOException, 
            CsvDataTypeMismatchException,
            CsvRequiredFieldEmptyException {
        Writer writer = new FileWriter("testfile.csv");
     StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer).build();
     beanToCsv.write(t);
     writer.close();        
    }
}
rothbart
  • 111
  • 2
  • 6

8 Answers8

13

I was getting a similar error, try adding a default constructor for the class you want to convert CSV into, it worked for me.

Supreet Singh
  • 882
  • 12
  • 9
8

If you are using Lombok, be sure to add a @NoArgConstructor on top of your Pojo.

SoftwareSavant
  • 9,467
  • 27
  • 121
  • 195
4

Through elimination, I discovered that the getter methods' names must match the properties' names. With the correction below, now I can write to CSVs from a list of objects.

//...
    public int getFieldx() {
        return fieldx;
    }
    public int getFieldy() {
        return fieldy;
    }
    public void setFieldx(int x) {
        this.fieldx = x;
    }
    public void setFieldy(int y) {
        this.fieldy = y;
    }
//...
rothbart
  • 111
  • 2
  • 6
  • Wow. That was unexpected. Pretty much every parser/serialization lib I have ever used either (a) does not need getters/setters or (b) has the annotations directly on the access methods... – Qw3ry Nov 18 '19 at 10:03
2

In my case, the constructor was not declared public!

Akshay
  • 3,558
  • 4
  • 43
  • 77
2

I have also faced similar issue.

Error message: Basic instantiation of the given bean type (and subordinate beans created through recursion, if applicable) was determined to be impossible

Means, it is trying to create Object but since bean class does not have public constructor hence its failing.

Resolution: Look at your bean class, it must have public constructor. If you have private or default then it will not work.

happy learning :)

Kushwaha
  • 850
  • 10
  • 13
0

My case was because I was testing the lib so I created a non-public bean file that was the problem so make sure that the bean file is a public class file since the lib uses CGLIB that proxies the class so it needs to access it

Youans
  • 4,801
  • 1
  • 31
  • 57
0

In my case it was because of the final keyword:

@Data
@Accessors(chain = true)
public class CsvFile {

    @CsvBindByName(column = "ColumnOne")
    private final String columnOne;
}

Worked fine after I removed the final keyword.

0

In my case, I had both default and parameterized constructor. The problem was resolved after adding getters and setters.

I used lombok for this purpose but I believe, after looking at other answers, that you'll have to make use of standard names for getters and setters. Custom names won't work.

flyingfishcattle
  • 1,817
  • 3
  • 14
  • 25