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.}
这是我的代码。使用反射我从类对象中获取数据,在上面的循环中,我设置了过程输入的参数。但是,它会保存一些整数值,并在第7行的某些位置抛出java.lang.NullPointerException
。
接受这些值:
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
答案 0 :(得分:1)
正如我猜测field.get(obj)
(有时)返回null
所以你应该检查它是null
还是以某种方式(取决于代码的逻辑)不允许它成为null
{{1}}。
我将此作为答案原因发布,鉴于您提供的信息我们可以告诉您问题出在哪里,而不是导致问题的原因。
答案 1 :(得分: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
值不对应而不是空的,并且它可能会失败IndexOutOfBoundsException
1}}当field.getType()
类似于shortpackage.Integer
时。
取而代之的是
Integer.class.equals(field.getType()) || Integer.TYPE.equals(field.getType())
Integer.TYPE
是int
基元类型的伪类。
第三,您似乎在编写自己的数据库抽象层。那里有大量的ORB可以为你做这件事。我鼓励你改用其中一个。
答案 2 :(得分:0)
我发现了这个错误。 callablestatement获取被调用过程的签名。参数应作为区分大小写的参数传递。我的程序正在接收FileOpsTypeID
,我正在通过FileOpsTypeId
。改变案例使其有效。
抱歉延迟回复。对不起,我没有提供完整的细节(程序)。