ArrayIndexOutOfBoundsException ExecuteBatch() on PreparedStatement - mysql

I'm adding 483 objects to a database with preparedStatements and ExecuteBatch().
When I run this code, all the objects are correctly added to the database but after a while the program throws:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 484
at com.mysql.jdbc.StatementImpl.processMultiCountsAndKeys(StatementImpl.java:1417)
at com.mysql.jdbc.PreparedStatement.executePreparedBatchAsMultiStatement(PreparedStatement.java:1515)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1389)
at model.database.SQLCommand.insertMeasurements(SQLCommand.java:110)
at model.database.SQLCommand.addDatasetToDb(SQLCommand.java:31)
at tests.readText.main(readText.java:35)
Here is my code:
private static List<Long> insertMeasurements(List<Measurement> measurements, long did) throws SQLException {
conn.setAutoCommit(false);
List<Long> mids = new ArrayList<Long>();
String sql = "INSERT INTO doses (CPS, ground, total) VALUES (?, ?, ?);" + " " +
"INSERT INTO places (x, y, z, speed) VALUES (?, ?, ?, ?);" + " " +
"INSERT INTO measurements (time, place, note, dose, id_dataset) VALUES (?, (SELECT MAX(ID) FROM places), ?, (SELECT MAX(ID) FROM doses), ?)";
try (
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
) {
for(Measurement measurement: measurements) {
ps.clearParameters();
double cps = measurement.getDose().getCps();
double ground = measurement.getDose().getGround();
double total = measurement.getDose().getTotal();
ps.setDouble(1, cps);
ps.setDouble(2, ground);
ps.setDouble(3, total);
double x = measurement.getPlace().getX();
double y = measurement.getPlace().getY();
double z = measurement.getPlace().getZ();
double speed = measurement.getPlace().getSpeed();
ps.setDouble(4, x);
ps.setDouble(5, y);
ps.setDouble(6, z);
ps.setDouble(7, speed);
String time = measurement.getDate().toString();
String note = measurement.getNote().toString();
ps.setString(8, time);
ps.setString(9, note);
ps.setObject(10, did);
ps.addBatch();
}
ps.executeBatch();
conn.commit();
ResultSet rs = ps.getGeneratedKeys();
while (rs.next()) {
long id = rs.getLong(1);
mids.add(id);
}
} catch (SQLException e) {
throw new SQLException("Can't add the measurement."+e.toString()+"\n" );
}
return mids;
}

Related

Rollback transaction not working properly

In database manipulation command such as insert, update or delete can sometime throws exception due to invalid data. To protect the integrity of application data we must make sure when we a transaction was failed we must rollback
PreparedStatement ps = null;
Connection conn = null;
try {
conn = DriverManager.getConnection( URL, USERNAME, PASSWORD );
String query = "INSERT INTO tbl1(id, username) " +
"VALUES (?, ?)";
ps = conn.prepareStatement( query );
ps.setString( 1, "javaduke" );
ps.execute();
query = "INSERT INTO tbl2 (id, tbl1_id, " +
"quantity, price) VALUES (?, ?, ?, ?)";
ps = conn.prepareStatement( query );
ps.setInt( 1, id );
ps.setInt( 2, tbl_id );
ps.setInt( 3, 10 );
ps.setDouble( 4, 29.99 );
ps.execute();
}
catch ( SQLException e )
{
conn.rollback()
e.printStackTrace();
}
I guess this is Java.
Right after you get your connection object, turn off autocommit, like so.
conn = DriverManager.getConnection( URL, USERNAME, PASSWORD );
conn.setAutoCommit(false);
Right after your last execute() do this.
conn.commit();
Then the rollback() in your exception handler should do what you expect.
This should extend the scope of your transaction to beyond a single SQL query.

"JSP First Connection cause second connection not running when it had ended"

I'm trying to get two data(GenreID & GameID) from two different tables(genre & games) and insert them into another table(games_genre). However, it will close the connection to the database after inserting the GenreID successfully even though i had created another new connection to the database.
I have tried to create connection1 and connection2 to the same database. Connection1 is used to insert GenreID and connection2 is used to insert GameID
<%# page import="java.sql.*,java.util.*,java.text.*,java.text.SimpleDateFormat" %>
String gametitle = request.getParameter("gametitle");
String [] checkbox1 = request.getParameterValues("checkbox");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String connURL ="jdbc:mysql://localhost/assignment?user=root&password=root&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(connURL);
Connection conn2 = DriverManager.getConnection(connURL);
Statement stmt = conn.createStatement();
if (checkbox1!= null){
for(String s: checkbox1){
String sqlStr2 = "Select * FROM genre WHERE GenreName='" + s + "'";
ResultSet rs = stmt.executeQuery(sqlStr2);
while(rs.next()){
String genreid = rs.getString("GenreID");
String sqlStr3 = "INSERT INTO games_genre(GenreID) VALUES ('" + genreid + "')";
int j = stmt.executeUpdate(sqlStr3);
if (j>0) {
out.println("Adding GenreID Successfully!");}
}
}
}
conn.close();
Statement stmt2 = conn2.createStatement();
String sqlStr4 = "Select * FROM games WHERE GameTitle='" + gametitle +"'";
ResultSet rs2 = stmt2.executeQuery(sqlStr4);
if(rs2.next()){
String gameid = rs2.getString("GameID");
String sqlStr5 = "INSERT INTO games_genre(GameID) VALUES ('" + gameid + "')";
int k = stmt2.executeUpdate(sqlStr5);
if (k>0) {
out.println("Adding GameID Successfully!");
}
}
conn2.close();
} catch (Exception e) {
out.println("Error :" + e);
}
Adding Game Successfully! Adding GenreID Successfully! Error :java.sql.SQLException: Operation not allowed after ResultSet closed
I don't understand that why do you need to create two Connection as you need to access same database . So ,just create multiple Statement to execute multiple query like below :
Statement stmt=null;
Statement stmt2=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String connURL ="jdbc:mysql://localhost/assignment?user=root&password=root&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(connURL);
stmt = conn.createStatement();
if (checkbox1!= null){
....
}
<!--using same conn object -->
stmt2 = conn.createStatement();
String sqlStr4 = "Select * FROM games WHERE GameTitle='" + gametitle +"'";
ResultSet rs2 = stmt2.executeQuery(sqlStr4);
if(rs2.next()){
...
}
<!--finally close connection-->
conn.close();
} catch (Exception e) {
out.println("Error :" + e);
}
Note : Also try using PreparedStatement for preventing from Sql Injection as concatenating values into a query string is unsafe .

Update Mysql tables upon inserting into another table

I have 2 tables, the first tables is a transactions table which has records of all transactions, and the second table is the savings table which has the total of all transactions amounts.
INSERT INTO `groupsavings`.`transactions`
(`transactions_id`, `shareholder_id`, `transactions_type`,
`transactions_date`, `amount`, `pool`)
VALUES (NULL, '1', 'credit', '2019-01-01', '100', 'poolone');
INSERT INTO `groupsavings`.`transactions`
(`transactions_id`, `shareholder_id`, `transactions_type`,
`transactions_date`, `amount`, `pool`)
VALUES (NULL, '1', 'credit', '2019-01-01', '50', 'poolone');
UPDATE `groupsavings`.`saving_pool`
SET `pool_value` = '100'
WHERE `saving_pool`.`Pool_name` = 'poolone';
UPDATE `groupsavings`.`saving_pool`
SET `pool_value` = '150'
WHERE `saving_pool`.`Pool_name` = 'poolone';
I want the savings table to cumulatively add to the savings table upon inserting into transactions table.
I guess you want to automatically update the savings table with the sum of the current amount in transaction table.
You can try this method assuming you named your database connection variables like this ( Connection con, PreparedStatement pst, ResultSet rs)
public void insertt(){
String trans_id = "";
String share_id = "";
String trans_type = "";
String trans_date = "";
String amt = "";
String poolname = "";
try{
String sql = " INSERT INTO groupsavings.transactions (transactions_id, shareholder_id, transactions_type, transactions_date, amount, pool)VALUES (?, ?, ?, ?, ?, ?)";
pst = con.prepareStatement(sql);
pst.setString(1, trans_id);
pst.setString(2, share_id);
pst.setString(3, trans_type);
pst.setString(4, trans_date);
pst.setString(5, amt);
pst.setString(6, poolname);
pst.execute();
String sql2 = "select sum(amount) from groupsavings.transactions WHERE saving_pool.pool_name = ’"+poolname+"' ";
pst = con.prepareStatement(sql2);
rs = pst.executeQuery();
int sum = 0;
while(rs.next()){
sum = rs.getInt(0);
String newpool = String.valueOf(sum);
}
String sql3 ="UPDATE groupsavings.saving_pool SET pool_value = ’"+newpool+"' WHERE saving_pool.pool_name =’"+poolname+"' ";
pst = con.prepareStatement(sql3);
pst.execute();
}
catch(SQLException e){}
}

How to insert data to a sqlite database with table name as variable

I would like to insert data into my sqlite data base but with a variable as the name of the table where the data should be entered.
try {
Random rand = new Random();
uniqueID = rand.nextInt(9998) + 1; //Generates a random number from 1 - 9999 inclusively
String dateStart = day1.getText() + "/" + month1.getText() + "/" + year1.getText();
String dateEnd = day2.getText() + "/" + month2.getText() + "/" + year2.getText();
String projectN = projectName.getText();
String addr = address.getText();
//String engineerN = engineerName.getText();
//String engineerP = engineerPassword.getText();
Class.forName("org.sqlite.JDBC");
conn2.setAutoCommit(false);
PreparedStatement ps = conn2.prepareStatement("insert into "My table name" (uniqueid,name,address,startingdate,estcompletion) values(?,?,?,?,?,?)");
ps.setInt(1, uniqueID);
ps.setString(2, projectN);
ps.setString(3, addr);
ps.setString(4, dateStart);
ps.setString(5, dateEnd);
//ps.setString(6, engineerN);
ps.execute();
ps.close();
conn2.commit();
conn2.close();
}
catch ( Exception e1) {
System.err.println( e1.getClass().getName() + ": " + e1.getMessage() );
System.exit(0);
}
}
}
public String JJI() {
return projectName.getText();
}
}
"My table name" in the prepared statement is the place where I want to put my table name getting it from projectName.getText(); at the end. The user enters projectname.getText in another class.
Thank you for the help!
Store your table name in a String variable (how you like): String tableName = "users";
Make a query variable that contains your SQL query:
String query = "insert into '" + tableName + "' (uniqueid,name,address,startingdate,estcompletion) values(?,?,?,?,?,?)";
If you would like to have variables to insert, replace the "?" with your variable names as you have done in your code:
ps.setInt(1, uniqueID);
ps.setString(2, projectN);
ps.setString(3, addr);
ps.setString(4, dateStart);
ps.setString(5, dateEnd);
Execute the query:
PreparedStatement ps = conn2.prepareStatement(query);
ps.execute();

Insert values in existing record. sqlite using prepared statement

I want to insert values into an existing record using prepared statment. The value of that record is the last record inserted, I tried LAST function and MAX but it didn't seems to work, also I tried SELECT statment inside INSERT with no luck.
public static void insertCoordinates(){
java.sql.Connection c = null;
try {
String str1 = Singelton.getInstance().getTxtField1().getText();
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:timeline_DB.db");
c.setAutoCommit(false);
PreparedStatement preparedStatement = c.prepareStatement("insert into event_table(bar_length, x_bar, y_bar) values (?, ?, ?) WHERE event_title =?");
preparedStatement.setInt(1, CanvasNewTimeLine.Event_length);
preparedStatement.setInt(2, CanvasNewTimeLine.x);
preparedStatement.setInt(3, CanvasNewTimeLine.H_LINE);
preparedStatement.setString(4,str1);
preparedStatement.executeUpdate();
c.commit();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
System.err.println("problem");
}
System.out.println("yesssssss successfully");
}
I used update instead of insert:
public static void insertCoordinates(){
java.sql.Connection c = null;
try {
String str1 = Singelton.getInstance().getTxtField1().getText();
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:timeline_DB.db");
c.setAutoCommit(false);
String updateTableSQL = "UPDATE event_table SET bar_length = ?, x_bar=?, y_bar=? WHERE event_title = ?";
PreparedStatement preparedStatement = c.prepareStatement(updateTableSQL);
preparedStatement.setInt(1, CanvasNewTimeLine.Event_length);
preparedStatement.setInt(2, CanvasNewTimeLine.x);
preparedStatement.setInt(3, CanvasNewTimeLine.H_LINE);
preparedStatement.setString(4,str1);
// execute
preparedStatement .executeUpdate();
c.commit();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
System.err.println("problem");
}
System.out.println("yesssssss successfully");
}