I am implementing an JAVA application which takes data from different URL’s and store this data to a databse.Each table has it’s own collections of URL’s from which it receives the data. I am doing this by implementing a preparedstatement for each table, get data from the URL, bind data to preparestatement and adding data as a batch until all the URL’s for a table are finished. And then doing executeBatch on the prepare statement. I do have some 6-8 tables and each table has some 200 rows. I am doing the same procedure for each table but after updating 3-4 tables my executeBacth is thrwoing an exception which says :
java.sql.SQLException: SQL Exception : [Microsoft][ODBC Driver
Manager] Invalid string or buffer length at
sun.jdbc.odbc.JdbcOdbcPreparedStatement.setObject(JdbcOdbcPreparedStatement.java:1438)
at
sun.jdbc.odbc.JdbcOdbcPreparedStatement.setObject(JdbcOdbcPreparedStatement.java:1073)
at
sun.jdbc.odbc.JdbcOdbcPreparedStatement.emulateExecuteBatch(JdbcOdbcPreparedStatement.jjva:2104)
at
sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeBatchUpdate(JdbcOdbcPreparedStatement.java:1782)
at
sun.jdbc.odbc.JdbcOdbcStatement.executeBatch(JdbcOdbcStatement.java:911)
at FaoClient.CFaoTable.InsertFromPartialSource(CFaoTable.java:174)
I have tested the same program by changing the order of fetching the data for tables but it is always throwing exception after inserting data 4-5 tables. I feel that it is like some memory leak situation but as I know JAVA grabage collector will never let this situaion happen. I am very new to this JAVA world so I might be wrong. I am pasting the part of my code which uses java.sql.* for purpose of inserting the records.
private boolean BindValueToStmt(PreparedStatement ps, int index, TableCol.ColType type, String ColVal) {
if ((ps == null) || (ColVal == "")) {
return false;
}
try {
switch (type) {
case INTEGERT: {
ps.setInt(index, Integer.parseInt(ColVal));
return true;
}
case STRINGT: {
ps.setString(index, ColVal);
return true;
}
case REALT: {
ps.setFloat(index, Float.parseFloat(ColVal));
return true;
}
case DOUBLET: {
ps.setDouble(index, Double.parseDouble(ColVal));
return true;
}
default:
ps.setNull(index, java.sql.Types.NULL);
}
return true;
} catch (SQLException E) {
System.out.println("Error in Setting the value of the col in table: " + Name + E);
E.printStackTrace();
return false;
}
}
private String CreatePreparedInsertStatement() {
StringBuilder insertStmt = new StringBuilder("insert into " + Name + "(");
String val = " values (";
for (int index = 0; index < Columns.size(); index++) {
TableCol col = Columns.get(index);
if (index != Columns.size() - 1) {
String Stmt = col.GetColName() + ", ";
insertStmt.append(Stmt);
val += "?, ";
} else {
String Stmt = col.GetColName() + ")";
insertStmt.append(Stmt);
val += "?)";
}
}
insertStmt.append(val);
return insertStmt.toString();
}
And below is the code which is actually inserting the data.
private boolean InsertFromPartialSource(Connection conn, SAXReader reader) {
try {
if (conn == null || reader == null) {
return false;
}
//Some Code not realted to java.sql
conn.setAutoCommit(false);
String strPs= CreatePreparedInsertStatement();
PreparedStatement ps = conn.prepareStatement(strPs);
//Some Code not realted to java.sql
for (int index = 0; index < Columns.size(); index++) {
TableCol col = Columns.get(index);
//Some Code not realted to java.sql
if (!BindValueToStmt(ps, index + 1, col.GetColType(), colVal)) {
ps.setNull(index + 1, TableCol.GetSqlColTypeFrmType(col.GetColType()));
}
}
rowCount++;
System.out.println(rowCount + "rows has been extracted for table \" " + Name);
ps.addBatch();
}
if (rowCount > 0) {
int RecordsUpdated[] = ps.executeBatch();
}
conn.commit();
conn.setAutoCommit(true);
ps.close();
return true;
}
I have only pasted the part of the function InsertFromPartialSource which is relevant to database update for clarity. Can someonw please indicate what things going wrong here?
The solution to above problem is:
Change your MySql Connector or Driver to MySqlJDBC driver. It can be
found on below link:
http://dev.mysql.com/downloads/connector/j/5.1.html
Consider switching to the real JDBC driver for your database (if there is one). The JdbcOdbc bridge is rather bad, specific JDBC drivers usually work better.