Отражение: выдает java.lang.NullPointerException

1
1.for (Field field : fields) {
2.    if (p.contains(field.getName())) {
3.        if(field.getType().toString().split("[.]")[2].equals("String"))
4.            callableStatement.setString(field.getName(), field.get(obj).toString());
5.        else if(field.getType().toString().split("[.]")[2].equals("Integer"))
6.            callableStatement.setInt(field.getName(), (int)field.get(obj));
7.        System.out.println(field.get(obj).toString());
8.    }
9.}

Это мой код. Используя отражение Я беру данные из объекта класса и в приведенном выше цикле, я устанавливаю параметры для ввода процедуры. Тем не менее, он сохраняет некоторые целочисленные значения и бросает java.lang.NullPointerException для некоторых в строке номер 7.

Эти значения принимаются:

this.DI_StDate = Common.getDateStamp(date); // Integer
this.DI_StTime = Common.getTimeStamp(date); // Integer

От Common.java

public static Integer getDateStamp(Date d) {
    return Integer.parseInt(requiredDate.format(d));
}

public static Integer getTimeStamp(Date d) {
    return Integer.parseInt(requiredTime.format(d));
}

Это исключает:

this.FileOpsId = new Integer(1);            // Integer
this.FileTypeOpsId = 1;                     // Integer

Пожалуйста, предложите, где я ошибаюсь.

Это мои ученики:

public class DIConnect {
    public Integer PROC_ID;
    public String APIKey;
    public String Username;
    public String pwd;
    public String StreamKey;

    public Integer DI_StDate;
    public Integer DI_StTime;

    public String FileNamePath;
    public Integer FileOpsTypeId;
    public String ConfigLabel;
    public Integer FileOpsId;

    public Integer End_Date;
    public Integer End_Time;

    public DIConnect(String FileNamePath, String ConfigLabel, Integer FileOpsTypeId, Integer StartDate, Integer StartTime) {
        this.FileNamePath = FileNamePath;
        this.ConfigLabel = ConfigLabel;
        this.FileOpsTypeId = FileOpsTypeId;
        this.DI_StDate = StartDate; // accepted
        this.DI_StTime = StartTime; // accepted
        this.FileOpsId = new Integer(1); // NOT ACCEPTED
    }
}

Это вызов метода main().

DIConnect DIC = new DIConnect(filePath, "File", 1, Common.getDateStamp(date), Common.getTimeStamp(date));
DIC.InsertFileOperation();

DIConnect.java:

public Integer InsertFileOperation() {
        String[] params = {"FileNamePath", "FileOpsId", "ConfigLabel", "DI_StDate", "DI_StTime"};
        DatabaseOperation db = new DatabaseOperation();
        if(db.openConnection()) {
            this.PROC_ID = db.executeProcedure("sp_InsertIntoFileOpsMaster", params, this);
            db.closeConnection();
        }
        return this.PROC_ID;
    }

Database.java

public Integer executeProcedure(String proc, String[] params, Object obj) {
        int Id = 0;
        try {
            String paramString = StringUtils.repeat("?, ", params.length + 1).trim();
            paramString = paramString.substring(0, paramString.length() - 1);
            proc = "{CALL " + proc + "(" + paramString + ")}";
            callableStatement = conn.prepareCall(proc);

            Class cls = obj.getClass();
            Field[] fields = cls.getFields();
            List<String> p = Arrays.asList(params);

            for (Field field : fields) {
                if (p.contains(field.getName())) {
                    if(field.getType().toString().split("[.]")[2].equals("String"))
                        callableStatement.setString(field.getName(), field.get(obj).toString());
                    else if(field.getType().toString().split("[.]")[2].equals("Integer"))
                        callableStatement.setInt(field.getName(), (int)field.get(obj));
                    System.out.println(field);                        
//                    System.out.println(field.get(obj).toString());
                }
            }
            callableStatement.registerOutParameter("Id",java.sql.Types.INTEGER);
            callableStatement.executeUpdate();
            Id = callableStatement.getInt("Id");

        } catch (SQLException | IllegalArgumentException | IllegalAccessException ex) {
            Logger.getLogger(DatabaseOperation.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex){
          System.out.println(ex.getMessage());
        } finally {
            return Id;
        }
    }

ВЫВОД

public java.lang.Integer airteldemo.DIConnect.DI_StDate
public java.lang.Integer airteldemo.DIConnect.DI_StTime
public java.lang.String airteldemo.DIConnect.FileNamePath
public java.lang.String airteldemo.DIConnect.ConfigLabel
null
  • 2
    Каков результат, если вы попытаетесь напечатать field ?
  • 0
    field.getName() дает имя поля, т.е. FileOpsId и FileTypeOpsId. Кроме того, (int)field.get(obj).value дает значение
Показать ещё 4 комментария
Теги:
reflection

3 ответа

0
Лучший ответ

Я нашел ошибку. Callablestatement получает подпись для вызываемой процедуры. Параметры должны передаваться как чувствительные к регистру параметры. Моя процедура FileOpsTypeID их как FileOpsTypeID и я проходил FileOpsTypeId. Изменение дела заставило его работать.

Извините за задержанный ответ. Также извините, я не представил полную информацию (процедуру).

1

В вашем коде есть несколько проблем.


Во-первых, поля могут иметь нулевые значения в java. Если вы принимаете аргумент типа Object вам просто нужно принять это и отобразить null значения в значения SQL, возможно, на основе рассуждений о типе столбца базы данных.

Вместо использования field.get(obj).toString() который не работает с null значениями поля, используйте String.valueOf(field.get(obj))


второй

else if(field.getType().toString().split("[.]")[2].equals("Integer"))

потому что он принимает java.lang.Integer поэтому может сбой с ClassCastException, не является нулевым, поскольку (Integer) null не соответствует ни одному значению int, и он может завершиться ошибкой с field.getType() IndexOutOfBoundsException когда field.getType() - это что-то вроде shortpackage.Integer.

Вместо этого

Integer.class.equals(field.getType()) || Integer.TYPE.equals(field.getType())

Integer.TYPE - псевдокласс для примитивного типа int.


В-третьих, вы, кажется, пишете свой собственный уровень абстракции базы данных. Там много ORB, которые должны сделать это для вас. Я рекомендую вам использовать один из них.

  • 0
    Хм ... Я передаю значения по умолчанию для целочисленных типов, которые генерируют исключение. Я приму ваш совет по использованию внешних продуктов. Но является ли ваш ответ в любом случае ответом на мое решение?
  • 0
    @SameerAnand, корень вашей проблемы в том, что field.get(obj) может быть нулевым, если !field.getType().isPrimitive() . Поскольку он может быть нулевым, вам нужно планировать нулевые результаты.
Показать ещё 1 комментарий
1

Как я уже догадался, field.get(obj) (иногда) возвращает null поэтому вы должны проверить, является ли оно null или каким-то образом (в зависимости от логики вашего кода) не позволяют ему стать null.

Я размещаю это как причину ответа, учитывая предоставленную вами информацию, мы можем просто сказать вам, где проблема, а не то, что ее вызывает.

  • 0
    Я предлагаю вам задать еще один вопрос или просто добавить необходимую информацию в свое сообщение (не в качестве комментария), чтобы все (включая меня) могли ее правильно понять.
  • 0
    Я обновил предварительные условия.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню