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
Я нашел ошибку. Callablestatement получает подпись для вызываемой процедуры. Параметры должны передаваться как чувствительные к регистру параметры. Моя процедура FileOpsTypeID
их как FileOpsTypeID
и я проходил FileOpsTypeId
. Изменение дела заставило его работать.
Извините за задержанный ответ. Также извините, я не представил полную информацию (процедуру).
В вашем коде есть несколько проблем.
Во-первых, поля могут иметь нулевые значения в 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, которые должны сделать это для вас. Я рекомендую вам использовать один из них.
field.get(obj)
может быть нулевым, если !field.getType().isPrimitive()
. Поскольку он может быть нулевым, вам нужно планировать нулевые результаты.
Как я уже догадался, field.get(obj)
(иногда) возвращает null
поэтому вы должны проверить, является ли оно null
или каким-то образом (в зависимости от логики вашего кода) не позволяют ему стать null
.
Я размещаю это как причину ответа, учитывая предоставленную вами информацию, мы можем просто сказать вам, где проблема, а не то, что ее вызывает.
field
?field.getName()
дает имя поля, т.е. FileOpsId и FileTypeOpsId. Кроме того,(int)field.get(obj).value
дает значение