I have a task. I need to randomly generate numbers between 1 and 1000000 and insert it to table called 'numbers' in database. Table 'numbers' has two columns: 'number' and 'quantity' If the number already existing in database, I need to increment quantity in the table. I have tried it in this way:
public void insertRow(String number) throws SQLException {
int cnt = getCount(number);
if (cnt == 0) {
insert(number);
} else if (cnt > 0) {
update(number);
}
}
getCount checking if number is existing in database:
private int getCount(String number) throws SQLException {
int cnt = 0;
String sql = "select count(number) as cnt from \"PUBLIC\".UNIQUE_NUMBER where number='" + number + "'";
Statement sta = getConnection().createStatement();
ResultSet rs = sta.executeQuery(sql);
if (rs.next()) {
cnt = rs.getInt("cnt");
}
return cnt;
}
Inserting to database:
private boolean insert(String number) throws SQLException {
String sql = "insert into \"PUBLIC\".UNIQUE_NUMBER (number, qty) values(?, ?)";
PreparedStatement ps = getConnection().prepareStatement(sql);
synchronized (this) {
try {
getConnection().setAutoCommit(false);
ps.setString(1, number);
ps.setInt(2, 0);
ps.addBatch();
ps.executeBatch();
getConnection().commit();
} catch (Exception e) {
LOGGER.error(e.toString());
try {
getConnection().rollback();
} catch (Exception ex) {
LOGGER.error(ex.toString());
}
return false;
} finally {
if (ps != null) {
ps.close();
}
getConnection().setAutoCommit(true);
}
}
return true;
}
And updating:
private boolean update(String number) throws SQLException {
String sql = "update \"PUBLIC\".UNIQUE_NUMBER set (qty) = (?) where number = ?";
int qty = selectQtyByNumber(number) + 1;
PreparedStatement ps = getConnection().prepareStatement(sql);
synchronized (this) {
try {
getConnection().setAutoCommit(false);
ps.setInt(1, qty);
ps.setString(2, number);
ps.executeUpdate();
getConnection().commit();
} catch (Exception e) {
LOGGER.error(e.toString());
try {
getConnection().rollback();
} catch (Exception ex) {
LOGGER.error(ex.toString());
}
return false;
} finally {
if (ps != null) {
ps.close();
}
getConnection().setAutoCommit(true);
}
}
return true;
}
SelectQtyByNumber method gets current quantity of number
private int selectQtyByNumber(String number) throws SQLException {
int qty = 0;
String sql = "select qty from \"PUBLIC\".UNIQUE_NUMBER where number='" + number + "'";
Statement sta = getConnection().createStatement();
ResultSet rs = sta.executeQuery(sql);
if (rs.next()) {
qty = rs.getInt("qty");
}
return qty;
}
When I run this code I always get BatchUpdateException: integrity constraint violation. But some number's quantity increases. Why is it happening? How to deal with it? Database is HSQLDB.
This is my Database constructor and getConnection method
public Database(String url, String user_name, String password) {
try {
Class.forName("org.hsqldb.jdbc.JDBCDriver");
this.connection = DriverManager.getConnection(url, user_name, password);
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
LOGGER.error("Database initialization exception: " + e.toString());
}
}
public Connection getConnection() {
return this.connection;
}