Ozan Kurt
Ozan Kurt

Reputation: 3866

Java how to fix "object is not an instance of declaring class" error?

I am trying to build a User class from SQL query ResultSet.

I am using my user class to get field names and use them as column names while building my SELECT query.

In this case my query has id and email in it's selections.

Query: "SELECT " + String.join(", ", columns) + " FROM " + table + ";"

public class User {

    private int id;
    private String email;

    public long getId() {

        return id;
    }

    public void setId(int id) {

        this.id = id;
    }

    public String getEmail() {

        return email;
    }

    public void setEmail(String email) {

        this.email = email;
    }
}

I have the problem in my parser class where I parse the results from database to an ArrayList<User>. Meanwhile I need to get the column types and field types dynamically.

Here is the loop of rows retrieved from the database:

while (resultSet.next()) {

    // columnCount is equal to the classes field count
    // since ResultSet starts indexes from 1, I added 1 to columnCount
    for (int i = 1; i < columnsCount + 1; i++) {
        // get the class of the wanted results
        // Ex: User
        Class<? extends Object> object = instance.getClass();

        // column name from index
        // Ex: id
        String columnName = metaData.getColumnName(i);
        // setter method name in the class
        // Ex: setId
        String setterName = "set" + Utils.firstLetterToUpperCase(columnName);

        Method method = null;

        Class<?> type = null;
        try {
            // array of declared fields of the class
            // Ex: [id, email]
            Field[] fields = object.getDeclaredFields();

            // type of that field
            // since ResultSet starts indexes from 1, I subtracted 1 from `i`
            // Ex: int
            type = fields[i - 1].getType();

            // Ex:
            //      Method is equal to the `setId(int id)`
            //      setterName = setId, type = int
            method = object.getDeclaredMethod(setterName, type);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // getter method to invoke on resultSet object to get the type dynamically
        // Ex: getterName = getId
        String getterName = "get" + Utils.firstLetterToUpperCase(type.getName());

        try {
            Method resultSetGetterMethod = null;

            try {
                // Ex:
                //          public int com.mysql.jdbc.ResultSetImpl.getInt(int) throws java.sql.SQLException
                //          easier: getInt(int x)
                //          getterName = getInt, type = int
                resultSetGetterMethod = resultSet.getClass().getMethod(getterName, type);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }

            // this part gives the error
            // "object is not an instance of declaring class"
            // --------------------------------------------------------- //
            // Exception: "object is not an instance of declaring class" //
            // --------------------------------------------------------- //
            method.invoke(object,

                    // it should call `getInt(int x)` method 
                    // on `resultSet` with `i` as the argument, which
                    // is the index of the int column in the `resultSet`
                    resultSetGetterMethod.invoke(resultSet, i) // This line
            );
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        results.add(object);
    }
}

I tried to explain what I tried to do in the comments, if it's not clear enough I can update the question.

I marked the code that throws the excetion with:

// --------------------------------------------------------- //
// Exception: "object is not an instance of declaring class" //
// --------------------------------------------------------- //

Why am I getting this error?

Upvotes: 0

Views: 1092

Answers (1)

Abdelhak
Abdelhak

Reputation: 8387

You invok the method with the class, but you need an instance of it, try this:

  method.invoke(instance,resultSetGetterMethod.invoke(instance,resultSet, i));

Upvotes: 2

Related Questions