executeUpdate blocked - java

When the code comes to the step "pstmt.executeUpdate()" it freezes and blocked and I didn't receive any SQL exception
This is works:
SQL = "INSERT INTO Procedure (file_path,id) VALUES ('/test/file_test.pdf',512);";
pstmt = con.prepareStatement(SQL,Statement.RETURN_GENERATED_KEYS);
pstmt.executeUpdate();
This doesn't work! and I don't receive any exception and it is blocked:
SQL = "INSERT INTO Procedure (file_path,id) VALUES (?,?);";
pstmt = con.prepareStatement(SQL,Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, "/test/file_test.pdf");
pstmt.setInt(2, 512);
pstmt.executeUpdate();
I don't understand why my code is blocked when I use the next solution (I mean setString and setInt).

procedure is a reserved keyword in SQL. May be it is causing due to this.
Change the Procedure table name to something else and try.
You can also try by change Procedure to `Procedure`.
I hope this works for you.

Using Try/Catch and the debugger will give you more information about the problem. I had a similair problem in the past and this is how i solved it. I'm not sure what the problem was but try this out
public void getCar(String carName) {
String[] key = {"PRIMARY_KEY_COLUMN"};
try(Connection con = super.getConnection()) {
String queryOne = "INSERT INTO Procedure (file_path,id) VALUES (?,?)";;
try(PreparedStatement pstmt = con.prepareStatement(queryOne, key)){
pstmt.setString(1, "/test/file_test.pdf");
pstmt.setInt(2, 512);
pstmt.executeUpdate();
int generatedKey = getGeneratedKey(pstmt));
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
// Do somthing if connection is set but exception thrown
}
} catch (SQLException e) {
e.printStackTrace();
// Do somthing else if connection couldn't be set
}
}
private int getGeneratedKey(PreparedStatement pstmt) throws SQLException {
int generatedKey = 0;
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()) {
generatedKey = rs.getInt(1);
}
rs.close();
return generatedKey;
}

hello guys bug found and fixed
Cause of the Bug : for example let us say we have 2 table B[Id, othercolumn] and A[Id, pathfile,fk_id_B]
I started a start transaction (UPDATE records id=512 ) on the table B
but i forget to close the transaction (connection.commit();connection.close()) before i stared other start a transaction on A so causes this freeze because the record (id=512) still used by the previews transaction
Solution: before start the transaction on A I close the transaction on B
thank you Guys for helps and participation :)

Related

"not Implemented by SQLite JDBC driver"

I have a database with User information, and I wanted to make a public static to return the database integers at any given time without having to make a void for every single one, but it's giving me this error:
0
java.sql.SQLException: not implemented by SQLite JDBC driver
at org.sqlite.jdbc3.JDBC3PreparedStatement.unused(JDBC3PreparedStatement.java:466)
at org.sqlite.jdbc3.JDBC3PreparedStatement.executeQuery(JDBC3PreparedStatement.java:506)
at dysanix.main.checkUserColumnInt(main.java:726)
at dysanix.main.main(main.java:50)
And this is my code:
public static int checkUserColumnInt(String column, String user) {
try {
Connection connection = DriverManager.getConnection("jdbc:sqlite:Database.db");
String query = "Select ? from userSettings WHERE user = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, column);
statement.setString(2, user);
ResultSet result = statement.executeQuery(query);
result.next();
int columnResult = result.getInt(column);
return columnResult;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
Does someone understand what I'm doing wrong? I tried to Google things, but changing code around moved me from one error to the next... so I'm not really certain anymore at this point.
I am running JDBC driver sqlite-jdbc-3.8.11.2.jar
PreparedStatement.executeQuery(String sql) is not implemented. I guess you just want to call executeQuery(). The query is defined by the PreparedStatement already.

Delete from database using Prepared Statement

I'm want to delete a person from the database "person" on a given id. It works if I don't use Prepared Statement (the first 5 unmarked lines of code in the try-statement).
But when I try to do it using Prepared Statement it does not work, and I canĀ“t figure out why?
The application gets stuck on prepStatement.executeUpdate();
Therefore I can't even see the value of executeUpdate (if I want to se how many Changes that are made).
I have a similar method, addPerson, where Prepered Statement works perfect. This really confuses me...
I appreciate your help.
private void removePerson() {
int id = Integer.parseInt(idField.getText());
PreparedStatement prepStatement = null;
try {
*/* Statement statement = connection.createStatement();
String sql = "DELETE FROM person WHERE id = '"+id+"'";
statement.executeUpdate(sql);
System.out.println("Person removed from database...");
ResultSet result = statement.executeQuery(sql);
*/*
String sql = "DELETE FROM person WHREE id = ?";
prepStatement = connection.prepareStatement(sql);
prepStatement.setInt(1, id);
prepStatement.executeUpdate();
System.out.println("Person removed from database...");
}
catch (SQLException se) {
se.toString();
}
finally {
try {
prepStatement.close();
}
catch (SQLException ex) {
ex.toString();
}
}
}

java.lang.NullPointerException ... Initializing the JDBC MYSQL connection

Please don't suggest me to use InternalFrame or Dialogs. I can't start the project from beginning.
Theme: I'm building a GUI program to display mark-sheet. I've taken 3 JFrames & 1 simple class...
Frame1.java
It's having 1 JTextField to enter roll_no. & 2 buttons to feedData in DB & showResult. feedData button calls Frame2 & showResult button calls Frame3.
Frame2.java
For feeding data have several JTextFields & Buttons that transfer content to mySQL DB.
Frame3.java
is a result window that fetches content from DB.
Support.java
Contains static variables & getter-setter methods for them
.....
.....//contains in Support.java
public boolean add() {
query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values(?,?,?,?,?)";
try {
PreparedStatement psmt = conn.prepareStatement(query);
psmt.setString(1, enroll);
psmt.setString(2, Sname);
psmt.setString(3, Fname);
psmt.setInt(4, sub1);
psmt.setInt(5, sub2);
psmt.setInt(6, sub3);
psmt.setInt(7, sub4);
psmt.setInt(8, sub5);
int y = 0;
y = psmt.executeUpdate();
if (y == 0) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
add() is called on pressing save button in Frame2.java . . . If catch block is executing, why println(query) printing NULL
Based on some of your question tags and responses in the comments to other answers and on the question itself, I'm presuming that somewhere in your code, you intend to call
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, username, password);
This is not happening before your add() method is called. In order to fix it, I'd recommend this (bulk of code borrowed from Vivek bhatnagar's answer):
try {
conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO `table`
(pid,tid,rid,tspend,description) VALUE
(?,?,?,?,?)");
pstmt.setString(1, pid );
pstmt.setString(2, tid);
pstmt.setString(3, rid);
pstmt.setInt(4, tspent);
pstmt.setString(5,des );
pstmt.executeUpdate();
} catch (Exception e) {
// whatever you want to do to handle the exception
} finally {
// close your connection
}
If you're on Java 7, set up like this:
try (Connection conn = DriverManager.getConnection(url, username, password)) {
try (PreparedStatement pstmt = conn.prepareStatement(/*sql here*/)) {
// Your code here
} catch (SQLException sqle) {
// handle exceptions from the statement
}
} catch (SQLException outerSqlEx) {
// handle exceptions from connecting
}
How could I tell what your problem was (general help for NullPointerException)?
NullPointerException is only thrown when you try to call a method on a null variable (and at a few other specific times, as noted in the API documentation). The easy way to locate a NullPointerException is to look for the line the stack trace indicates, and then look for the dots on the line. There's only two lines in your try block that can throw a NullPointerException.
Statement stmt = conn.createStatement();
// could be here ----^
and
y = stmt.executeUpdate(query);
// or --^
So let's look at the dots. The first one will throw when conn is null. The second one will throw when stmt is null. In your original code, which you've now edited in response to the other answers, you set the value of query after you called conn.createStatement();. Since query was still null in your catch block, we know that it hadn't yet been set, and thus it must be the first one, so conn is null at that point in the program.
Furthermore, since the API Documentation for createStatement
implies that it will either return a valid Connection object or throw an SQLException, we can be pretty sure that stmt will never be null when executeUpdate is called.
In your try block, you are calling a method that is possible to throw an exception before setting the variable in question:
Statement stmt = conn.createStatement();
query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values('" + getEnroll() + "','" + getSname() + "','"+getFname()+"',"+getSub1()+","+getSub2()+","+getSub3()+","+getSub4()+","+getSub5()+")";
Therefore, if your code fails on the conn.createStatement() line, it will enter the catch block without the query variable being initialized.
You can fix this simply by switching the order of the statements, or by putting the query line outside and before the try/catch blocks.
Adding to what #Southpaw answered :
you can use something like this also :
PreparedStatement pstmt = con.prepareStatement("INSERT INTO `table`
(pid,tid,rid,tspend,description) VALUE
(?,?,?,?,?)");
pstmt.setString(1, pid );
pstmt.setString(2, tid);
pstmt.setString(3, rid);
pstmt.setInt(4, tspent);
pstmt.setString(5,des );
pstmt.executeUpdate();
Kindly Note its benefits:
1."Query is rewritten and compiled by the database server"
If you don't use a prepared statement, the database server will have to parse, and compute an execution plan for the statement each time you run it. If you find that you'll run the same statement multiple times (with different parameters) then its worth preparing the statement once and reusing that prepared statement. If you are querying the database adhoc then there is probably little benefit to this.
2."Protected against SQL injection"
This is an advantage you almost always want hence a good reason to use a PreparedStatement everytime. Its a consequence of having to parameterize the query but it does make running it a lot safer. The only time I can think of that this would not be useful is if you were allowing adhoc database queries; You might simply use the Statement object if you were prototyping the application and its quicker for you, or if the query contains no parameters.

Inserting a list of values into Mysql

How do I insert a list of values into a column in a MySQL table.
Here is my project:
public void settingAmount(List<String>lst)throws Exception{
// Accessing driver from jar files
Class.forName("com.mysql.jdbc.Driver");
// here we create a variable for the connection called con
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/ozon","root","root");
// here we create our query
Statement stmt = (Statement) con.createStatement();
//performing insert operation :)
lst.toArray(ss);
for(String ins:ss){
double d=Double.parseDouble(ins);
String insert = "INSERT INTO storage_other(total) VALUES ("+ins+");";
//String insert = "INSERT INTO storage_other(amount) VALUES ("+ls+");";
// Here we are going to Execute the query
stmt.executeUpdate(insert);
System.out.print("Done Seccesfully :)");
}
}
What you want to do is use batches. Batches allow you to send a list of statements to be done at the same time.
Here is an example
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement("INSERT INTO storage_other(total) VALUES (?)");
for (String ins:ss){
ps.setObject(1, d);
ps.addBatch();
}
ps.executeBatch();
connection.commit();
This will be significantly faster than individual inserts on any table with indexes.
This is a method I used in order to insert some data in an Oracle SQL database.
private boolean submit(Connection con, String query){
try {
PreparedStatement preStatement;
preStatement = con.prepareStatement(query);
preStatement.executeQuery();
preStatement.close();
return true;
}catch (Exception e) {
System.out.println("Exception cought, updating log.");
return false;
}
}
You can prepare your insert statement and call this function to perform the action. Call it using your connection object and the query. It shall return true on completion false in case something goes wrong. If you want to log any errors, use e.getMessage() to get the error message as a String in the exception block.
As mentioned in the comments, try to use the PreparedStatement object to avoid SQL Injection attacks and also try to trim any ' you might have in your data.
Here's how I'd recommend you do it. A few thoughts:
Give the Connection to the object. That method should do one thing: the INSERT.
Should be transactional.
Should clean up resources when done.
Tell users to provide a List of Doubles if that is what the amounts are. Don't parse; let clients do that.
Here is complete code:
public class Inserter {
private static final String INSERT_SQL = "INSERT INTO storage_other(total) VALUES(?))";
private Connection connection;
public Inserter(Connection connection) {
this.connection = connection;
}
public int settingAmount(List<Double> amounts)throws SQLException {
int numAmountsInserted = 0;
PreparedStatement ps = null;
this.connection.setAutoCommit(false);
try {
ps = this.connection.prepareStatement(INSERT_SQL);
for(Double amount : amounts) {
ps.setDouble(1, amount);
numAmountsInserted += ps.executeUpdate();
}
this.connection.commit();
} catch (SQLException e) {
DatabaseUtils.rollback(this.connection);
throw e;
} finally {
DatabaseUtils.close(ps);
this.connection.setAutoCommit(true);
}
return numAmountsInserted;
}
}

How can I avoid ResultSet is closed exception in Java?

As soon as my code gets to my while(rs.next()) loop it produces the ResultSet is closed exception. What causes this exception and how can I correct for it?
EDIT: I notice in my code that I am nesting while(rs.next()) loop with another (rs2.next()), both result sets coming from the same DB, is this an issue?
Sounds like you executed another statement in the same connection before traversing the result set from the first statement. If you're nesting the processing of two result sets from the same database, you're doing something wrong. The combination of those sets should be done on the database side.
This could be caused by a number of reasons, including the driver you are using.
a) Some drivers do not allow nested statements. Depending if your driver supports JDBC 3.0 you should check the third parameter when creating the Statement object. For instance, I had the same problem with the JayBird driver to Firebird, but the code worked fine with the postgres driver. Then I added the third parameter to the createStatement method call and set it to ResultSet.HOLD_CURSORS_OVER_COMMIT, and the code started working fine for Firebird too.
static void testNestedRS() throws SQLException {
Connection con =null;
try {
// GET A CONNECTION
con = ConexionDesdeArchivo.obtenerConexion("examen-dest");
String sql1 = "select * from reportes_clasificacion";
Statement st1 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet rs1 = null;
try {
// EXECUTE THE FIRST QRY
rs1 = st1.executeQuery(sql1);
while (rs1.next()) {
// THIS LINE WILL BE PRINTED JUST ONCE ON
// SOME DRIVERS UNLESS YOU CREATE THE STATEMENT
// WITH 3 PARAMETERS USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
System.out.println("ST1 Row #: " + rs1.getRow());
String sql2 = "select * from reportes";
Statement st2 = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// EXECUTE THE SECOND QRY. THIS CLOSES THE FIRST
// ResultSet ON SOME DRIVERS WITHOUT USING
// ResultSet.HOLD_CURSORS_OVER_COMMIT
st2.executeQuery(sql2);
st2.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs1.close();
st1.close();
}
} catch (SQLException e) {
} finally {
con.close();
}
}
b) There could be a bug in your code. Remember that you cannot reuse the Statement object, once you re-execute a query on the same statement object, all the opened resultsets associated with the statement are closed. Make sure you are not closing the statement.
Also, you can only have one result set open from each statement. So if you are iterating through two result sets at the same time, make sure they are executed on different statements. Opening a second result set on one statement will implicitly close the first.
http://java.sun.com/javase/6/docs/api/java/sql/Statement.html
The exception states that your result is closed. You should examine your code and look for all location where you issue a ResultSet.close() call. Also look for Statement.close() and Connection.close(). For sure, one of them gets called before rs.next() is called.
You may have closed either the Connection or Statement that made the ResultSet, which would lead to the ResultSet being closed as well.
Proper jdbc call should look something like:
try {
Connection conn;
Statement stmt;
ResultSet rs;
try {
conn = DriverManager.getConnection(myUrl,"","");
stmt = conn.createStatement();
rs = stmt.executeQuery(myQuery);
while ( rs.next() ) {
// process results
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
} finally {
// you should release your resources here
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
} catch (SqlException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
you can close connection (or statement) only after you get result from result set. Safest way is to do it in finally block. However close() could also throe SqlException, hence the other try-catch block.
I got same error everything was correct only i was using same statement interface object to execute and update the database.
After separating i.e. using different objects of statement interface for updating and executing query i resolved this error. i.e. do get rid from this do not use same statement object for both updating and executing the query.
Check whether you have declared the method where this code is executing as static. If it is static there may be some other thread resetting the ResultSet.
make sure you have closed all your statments and resultsets before running rs.next. Finaly guarantees this
public boolean flowExists( Integer idStatusPrevious, Integer idStatus, Connection connection ) {
LogUtil.logRequestMethod();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement( Constants.SCRIPT_SELECT_FIND_FLOW_STATUS_BY_STATUS );
ps.setInt( 1, idStatusPrevious );
ps.setInt( 2, idStatus );
rs = ps.executeQuery();
Long count = 0L;
if ( rs != null ) {
while ( rs.next() ) {
count = rs.getLong( 1 );
break;
}
}
LogUtil.logSuccessMethod();
return count > 0L;
} catch ( Exception e ) {
String errorMsg = String
.format( Constants.ERROR_FINALIZED_METHOD, ( e.getMessage() != null ? e.getMessage() : "" ) );
LogUtil.logError( errorMsg, e );
throw new FatalException( errorMsg );
} finally {
rs.close();
ps.close();
}
A ResultSetClosedException could be thrown for two reasons.
1.) You have opened another connection to the database without closing all other connections.
2.) Your ResultSet may be returning no values. So when you try to access data from the ResultSet java will throw a ResultSetClosedException.
It happens also when using a ResultSet without being in a #Transactional method.
ScrollableResults results = getScrollableResults("select e from MyEntity e");
while (results.next()) {
...
}
results.close();
if MyEntity has eager relationships with other entities. the second time results.next() is invoked the ResultSet is closed exception is raised.
so if you use ScrollableResults on entities with eager relationships make sure your method is run transactionally.
"result set is closed" happened to me when using tag <collection> in MyBatis nested (one-to-many) xml <select> statement
A Spring solution could be to have a (Java) Spring #Service layer, where class/methods calling MyBatis select-collection statements are annotated with
#Transactional(propagation = Propagation.REQUIRED)
annotations being:
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
this solution does not require to set the following datasource properties (i.e., in JBoss EAP standalone*.xml):
<xa-datasource-property name="downgradeHoldCursorsUnderXa">**true**\</xa-datasource-property>
<xa-datasource-property name="resultSetHoldability">**1**</xa-datasource-property>

Categories