Any known issues with DELETE-statement in Java's MySQL-Connector? - java

I have checked around, and I have checked up the issue all over Google, tried all kind of solutions, but I haven't found any solution.
The issue is that the DELETE-statement isn't really working.
java.sql.Connection conn = new Connection().getConnection();
try {
conn = new Connection().getConnection();
PreparedStatement statement = (PreparedStatement) conn.prepareStatement("DELETE FROM _users WHERE _id = ?");
statement.setInt(1, 4);
statement.executeUpdate();
} catch (Exception e) {
System.out.println(e);
} finally {
try {
conn.close();
} catch (Exception e) {
System.out.println(e);
}
}
This is the code I am using, and for all I have understood statement.executeUpdate() is the method to use. I have also tried statement.execute() and all kinds of tries.
There is no exception, so no known error. The new Connection().getConnection() gives away an valid connection ( working with SELECT,INSERT,UPDATE ) and the user has permissions for SELECT,INSERT,UPDATE and DELETE.
I am currently using technology such as:
Java 6 (1.6)
mysql-connector-java-5.1.28.jar
and I also had the same experience with
mysql-connector-java-5.1.19.jar
So I would highly appreciate if anyone had the same problem as I seem to have, what it might be because of and/or how to fix it.
Thank you everyone at Stackoverflow. :) Hope this been relevant to anyone else.

To say that something isn't really working does not give us much to go on.
But I suggest that you read up on Transactions. See http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
Unless autoCommit is turned on, you will need to commit your transaction.
Also in your example, you use the ID with the value of 4 - does this really exist?

You always use the same id to delete from. So whether id 4 exists or not the statement will always execute.

Does the id 4 exist? You can issue this command over and over in mysql: DELETE FROM _users WHERE _id = 4;
So long as the table _users exists, you won't get any error. It'll just keep running. Verify that id 4 exists.

The problem has been resolved! So this answer is for future needs
My connection is set automaticely to conn.setAutoCommit(false) and this works for INSERT, UPDATE and SELECT, and for the DELETE-statement to work is to set connection to conn.setAutoCommit(true), and then add an conn.commit() to make the statement to go through.
Want to thank user2310289 for s/he's answer which helped alot.

Related

Returning Null vs Exception vs Contract

What would be considered an acceptable way of dealing with returning a record from a DB with the following 3 potential outcomes:
Db connection works, finds a user and returns a populated user object
Db connection works, doesn't find a user, returns a new user object
Db connection/query fails...
I'm for the most part aiming for design by contract:
class Scratch {
public User getUser(int id) {
try {
// Prepare SQL Query
PreparedStatement s = this.connection.prepareStatement(
"select * from get_user(?)"
);
// Provide SQL Parameters
s.setInt(1, id);
// Run our SQL
ResultSet rs = s.executeQuery();
rs.next();
// Extract data into Entity
User user = User.createFromDatabase(rs);
rs.close();
return user;
} catch(Exception e) {
e.printStackTrace();
}
return new User();
}
}
In the situation that the DB connection or query fails it's a little less obvious what I should do, I have a few options:
Return a new user object, because our method has agreed to return a user
Pro: This sticks to designing by contracts
Con: This makes it look like the user doesn't exist.
Return null since it didn't actually get a user.
Pro: This is totally clear that a user was not found
Con: Requires a null check
Throw an exception further up the chain.
Pro: Makes it explicitly clear the operation wasn't achieved
Con: Does not attempt to rectify issues where they happen
I'm leaning towards handling Exceptions as it avoids the billion-dollar mistake, and also maintains design by contract in normal situations.
However I'd like to know if there are any obvious pitfalls or if this is a familiar situation with a well established pattern to resolve it.
I would throw an exception and let the user know that the connection failed. Returning NULL is something I would never do because you won't know what the problem was.
I don't know why you would return "New user object" if you don't have connection to the database. You won't be able to save the user.
My choice will be to Throw an exception
Use Optional (please). This make explicit that the user could not be found in the database and avoid NullPointerException's.
Optional(User) if the user is found in the database
Empty if user is not found
If there is an Error you have two options:
Notify the client so it can get feedback and react to this failure. In this case throw an exception and handle it in the proper layer. This should be the default behaviour for most of the applications.
Hide it to the client, this is less common but some times the client doesn't care or you don't want to publish your failures. In that case just return an Empty.

Java: Cached RowSet insertRow fails: SQLException

So I'm trying to understand how to use the RowSet API, specifically CachedRowSet, and I feel like I've been bashing my head against a wall for the last hour or so and could use some help.
I've got some very simple tables set up in a MySQL database that I'm using to test this. I should also add that everything I'm attempting to do with RowSet I've been able to do successfully with ResultSet, which leads me to believe that the issue is with my usage of the ResultSet API, rather than the operation I'm attempting to do itself.
Anyway, I'm trying to insert a new row using ResultSet. I'll paste my code here, then add some notes about it below:
CachedRowSet rowSet = null;
try {
RowSetFactory rsFactory = RowSetProvider.newFactory();
rowSet = rsFactory.createCachedRowSet();
rowSet.setUrl("jdbc:mysql://localhost:3306/van1");
rowSet.setUsername("####");
rowSet.setPassword("####");
rowSet.setKeyColumns(new int[]{1});
} catch (SQLException e) {
e.printStackTrace();
}
String query = "select * from phone";
try {
rowSet.setCommand(query);
rowSet.execute();
printTable(rowSet);
rowSet.moveToInsertRow();
rowSet.setInt(1, 4);
rowSet.setString(2, "Mobile");
rowSet.setString(3, "1");
rowSet.setString(4, "732");
rowSet.setString(5, "555");
rowSet.setString(6, "1234");
rowSet.setString(7, "");
rowSet.insertRow();
rowSet.moveToCurrentRow();
rowSet.acceptChanges();
printTable(rowSet);
} catch (SQLException e) {
e.printStackTrace();
}
So, as you can see, I'm trying to update a table of phone numbers with a new phone number. Here are the details:
1) All the phone number fields are datatype char, so that leading zeroes are not lost.
2) I'm using the default CachedRowSet implementation provided by the JDBC API, as opposed to anything specific from the MySQL driver. Not sure if that matters or not, but I'm putting it here just in case. Also, I didn't see an option to import CachedRowSet from the driver library anyway.
3) I'm setting a value for every column in the table, because the RowSet API doesn't allow for rows to be inserted without a value for every column.
4) I've tried the operation using both the setter methods and the update methods. Same result either way.
5) As far as I can tell, I'm on the insert row when executing the insertRow() method. I also return to the current row before invoking acceptChanges(), but since my code never gets that far I can't really comment on that part.
6) The exception is a SQLException (no chained exception within it) thrown on the invocation of the insertRow() method. Here is the stack trace:
java.sql.SQLException: Failed on insert row
at com.sun.rowset.CachedRowSetImpl.insertRow(Unknown Source)
at firsttry.RowSetPractice.rowSetTest(RowSetPractice.java:87)
at firsttry.RowSetPractice.main(RowSetPractice.java:20)
So, I'm out of ideas. Any help would be appreciated. I've searched every thread on this site I could find, all I see is stuff about it failing on the acceptChanges() method rather than insertRow().

Java and MySQL query

I have problem with java and MySQL. My code:
Connection connection;
// ...
for (String query : updateAndInsertQuery) {
Statement stm = connection.createStatement();
stm.execute(query);
stm.close();
}
Statement stm2 = connection.createStatement();
System.out.println("Before query");
System.out.flush();
ResultSet Result = stm2.executeQuery(selectQuery);
System.out.println("After query");
System.out.flush();
int vfrom, vto;
while (Result.next()) {
// ...
}
When I run program i see in MySQL queries and run
show processlist;
selectQuery is visible on list wth status Sending data or Writing to net. On console print: Before query. Next
show processlist;
returns empty list, but application don't print After query. Do you have similar problem?
-- edit
I resolve my problem.
I think:
wen MySQL returns data and query isn't visible on processlist in MySQL
I should immediately get on console message: After query
but console was empty, java process works (cpu usage was 90-100%) so I think it was my mistake, but after 1h application throws Exception
Increase memory limit resolve my problem.
So I have next question why application throw exception after hour? Garbage collection try dealocate unised objects?
executing queries manually usually leads into many different problems - all of which are platform-specific and DB-specific. I think your best answer will be : "switch to ORM".
This framework has proven to be exceptionally good, wrappig all your SQL-data into Entities and transactions (if required) will resolve most of your problems at the same time - you will only need to annotate your entities and relationships correctly. Database-queries can be executed via JPA-"criteria"s which are platform-independent AND allow you to avoid a lot of problems as well as making your code READABLE.
Tutorial : http://www.vogella.com/tutorials/JavaPersistenceAPI/article.html
SO-question : https://stackoverflow.com/questions/743065/what-is-the-fastest-way-to-learn-jpa
With JPA, you wont need to care about statements or queries anymore (well, at least most of the time) and your mentioned problem will disappear - PLUS : it only takes 30-60min to implement.
Additional tip : use Maven & Eclipselink (JPA2 implementation) - thats a very powerful, portable combination

JDBC/Resultset error

My mysql-query in Java always stops (i.e. freezes and does not continue) at a certain position, which namely is 543,858; even though the table contains approx. 2,000,000 entries. I've checked this by logging the current result-fetching.
It is reproducible and happens every time at the very same position.
"SELECT abc from bcd WHERE DATEDIFF(CURDATE(), timestamp) <= '"+days+"'");
Addition: It definitely is a Java error, I've just tried out this statement in Navicat (50s running time).
The query seems to freeze after the log tells me that it's now adding the result of position 543,858.
try {
...
ResultSet res = new ResultSet();
PreparedStatement stmt = new PreparedStatement(); // prepare statmenet etc.
stmt.setFetchSize(Integer.MIN_VALUE);
res = stmt.executeQuery();
...
System.out.println(res.getStatement());
...
while (res.next())
treeSet.add(res.getString("userid"));
} catch (Exception e) {
e.printStackTrace();
}
Edit: We were able to figure out the problem. This method is fine and the returned result (500,000 instead of 2,000,000) is right as well (looked up in the wrong db to verify the amount); the problem was, that the next method-call that used the result of the one posted above takes literally forever, but had no logging-implemented. So I've been fooled by missing console-logs.
Thanks anyways!
I think you might be running out of memory after processing half a million records. Try assigning more memory using command line options -Xmx etc. See here for more info about command line options.
In mysql to use streaming ResultSets you have to specify more parameters, not only fetchSize.
Try:
stmt = conn.createStatement('select ...', java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
and see if that works.
It's documented in the ResultSet section.
Strange that it doesn't throw exception, but this is the only suspect I have. Maybe it starts garbage collection/flushes memory to disk and it takes so much time it doesn't get to throw it.
I would try to add to your query " LIMIT 543857" and then " LIMIT 543857" and see what happens.
If the above does not help, use the limit directive combined with order by.
I suspect that there is invalid entry in your table and the way to find it is binary search.

SQLite DB is locked exception, how do I unlock it if I haven't ever toyed with it?

java.sql.SQLException: database is locked
at org.sqlite.DB.throwex(DB.java:288)
at org.sqlite.NestedDB.prepare(NestedDB.java:115)
at org.sqlite.DB.prepare(DB.java:114)
at org.sqlite.Stmt.executeQuery(Stmt.java:89)
When I make a query I get this exception. I read up on it on SA and Google, and the most common conclusion is that someone started making another query which never finished. The problem I'm having is that I've never made a query on this DB on this machine before. I downloaded the db file from where I hosted it (I created it earlier) and haven't done anything with it, so I don't know why it would be locked. When I do a query using a program called SQLite Database Browser, it works just fine. Thanks for the help, I'll provide more info if need be, just let me know.
adapter = new DbAdapter();
ResultSet info;
ResultSet attributes;
for (int i = 1; i < 668; i++) {
if (i%50 == 0) {
System.out.print('.');
}
info = adapter.makeQuery("SELECT * FROM vehicles WHERE id = '" + i + "'");
attributes = adapter.makeQuery("SELECT * FROM vehicle_moves WHERE vehicle_id = '" + i + "'");
if(info.next()) {
base = new (info, attributes);
}
vehicleArray[i] = base;
}
System.out.println("Done.");
info.close();
attributes.close();
adapter.close();
Above is the code where this is occurring. I did some homework throughout my code and sure enough the problem is in this code, other DB queries work just fine. Anything jump out at you guys?
SQLite itself can most certainly handle doing a query while the results of another query are being processed. It'd be terribly useless if that couldn't be done! What's more likely to cause problems is if you've got two connections to the database open at once. I don't know that DbAdapter class at all – not what package it is in, or what module provides it – but if it is assuming that it can open many connections (or if it isn't maintaining proper connection hygiene) then that most certainly would be a cause of the sort of problems you're seeing. Look there first.

Categories

Resources