results.next() == false and there's no printing of data - java

results.next() is false, !results.next() in the while loop prints ResultSet closed
I've tried EVERYTHING. from doing Class.forName() to connection.setAutoCommit(false) nothing's working :/
public static void main(String[] args) throws Exception {
String query = "SELECT * FROM StudentInfo";
String url;
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection(url);
ps = connection.prepareStatement(query);
results = ps.executeQuery();
while (results.next()) {
print(results.getString("nameID"));
}
} catch (SQLException e) {
print(e.getMessage());
}
}
just prints out BUILD SUCCESSFUL without printing any of my data

The first thing to consider is to make sure that the table isn't empty.
Class.forName isn't even assigned to anything.
connection.setAutoCommit(false) is irrelevant here as that's more of a transaction detail. You don't need to worry about that for a query this simple.
I'd try running a query that you know works first. Maybe your connection isn't even correct or possibly null, thus never really executing the query. That's probably why your resultset is closed.
I also hope print() is from System.out or something that will actually print.

Related

Database connection with JDBC using Ucanaccess no output

I try to create a connection between JDBC and MS Access.
I follow the instruction as per this link. I am using IntelliJ Idea. Here I am sharing some snaps to describe my problem.
This is the code that I write down to make a connection with Database Database2. But as you can see there is no error neither any output. Now I am sharing the table structure and content on the table.
2nd picture is
My code is:
import java.sql.*;
public class Connection_sample {
public static void main(String[] args) {
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn= DriverManager.getConnection("jdbc:ucanaccess://D://tutorial/Database2.accdb");
Statement s = conn.createStatement();
s.executeQuery("select * from Student");
ResultSet rset = s.getResultSet();
while (rset.next()) {
System.out.println(rset.getInt(1)+""+rset.getInt(2));
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Can anyone help me to find the error?
Your problem is the result of using getResultSet() instead of using the result set returned by executeQuery(). You should only use getResultSet() in combination with execute().
A result set should only be obtained once, and it was already returned from executeQuery (which you ignored). When you called getResultSet, you - apparently - got an empty one (which technically violates the contract).

JDBC ResultSet closed in Java after several iterations

I am having a problem with a ResultSet being closed. What confuses me is that it works for a portion of the data and then closes. At first I thought it might be because of connection timeout but that doesn't seem the case.
This portion of the program pertains to comparing an .xlsx workbook to an already present SQL database and for lack of a better term merges/updates it.
First, in my CompareDatabase class I am calling a search function that searches an SQLite database for a specific string every 6 iterations.
int columnCount = 6;
dataPoint = dataPoint.replaceAll("Detail", "");
String[] temp = dataPoint.trim().split("\\s+");
System.out.println(Arrays.toString(temp));
for (String tempDataPoint : temp) {
if ( columnCount == 6) {
System.out.println(search(tempDataPoint, connection));
}
columnCount = 0;
} else {
columnCount++;
}
}
This search function (also in the CompareDatabase class is then supposed to search for the value and return a String (was originally a Boolean but I wanted to see the output).
private String search (String searchValue, Connection connection) throws SQLException {
PreparedStatement pStatement = null;
pStatement = connection.prepareStatement("SELECT * FROM lotdatabase where (Vehicle) = (?)");
pStatement.setString(1, searchValue);
try (ResultSet resultSet = pStatement.executeQuery()){
return resultSet.getString(1);
}finally {
close(pStatement);
}
}
At the end you can see that the PreparedStatement is closed. The ResultSet should also be closed automatically (I read somewhere) but JDBC could possibly be being unreliable.
The Connection however is still open as it will be searching some 200+ strings and opening and closing that many times did not seem like a good idea.
These functions are called by my main class here:
One is commented out since it will error out because of primary key violation.
public static void main(String[] args) {
SQLDatabase sqlDatabase = new SQLDatabase();
//sqlDatabase.convertToSQL("Database1.xlsx");
sqlDatabase.compare("Database2.xlsx");
}
I have a suspicion that I am going about a bunch of this wrong (on the aspect of managing connections an such) and I would appreciate a reference to where I can learn to do it properly.
Also, being that PreparedStatement can only handle one ResultSet I don't see that being my issue since I close it every iteration in the for loop.
If more code or explanation is required please let me know and I will do my best to assist.
Thank you for taking the time to read this.
So after a bit more Googling and sleeping on it here is what worked for me.
The search function in compareDatabase changed to this:
private Boolean search (String searchValue, Connection connection) {
PreparedStatement ps = null;
try {
ps = connection.prepareStatement("SELECT * FROM lotdatabase where " +
"(Vehicle) = (?)");
ps.setString(1, searchValue);
ResultSet resultSet = ps.executeQuery();
//The following if statement checks if the ResultSet is empty.
if (!resultSet.next()){
resultSet.close();
ps.close();
return false;
}else{
resultSet.close();
ps.close();
return true;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
And in the other function within compareDatabase I call the search function like this:
if (search(tempDataPoint, connection)) {
System.out.println("MATCH FOUND: " + tempDataPoint);
}else {
System.out.println("NOT FOUND: " + tempDataPoint);
}
This allows me to check the ResultSet and also be sure that it is closed.

JDBC Too Many Connections Error

I know this probably is a similar question from the rest, (well originally, before I tried something new, it was a bit unique but it never solved the main problem), but I probably need to discuss this with someone who can help because I could never get what's causing this despite already reading various posts from this site. Bottom line is I need to keep on making plenty of sequential queries but I ended up making too many connections.
What my program does is that it displays data about each member and that it's sort of a tree or network where, in order to get the data you need for each member, you have to scout through every other member that points to that current member (or child's data) , and the data of the member that points to the member that points to the current member (or grandchild's data) and so on. Hence, why I need to keep making queries cause I need to get the data off of each child. Each node has I think a minimum children of 5 and on my 34th member, it gave off that "Too Many Connections" error.
I have read how to open and close the Connections and all but am I still doing it incorrectly? I've tried changing the max connections but that's not really a long term solution for me. Here's how I do it:
public class SQLConnect {
private Connection con;
private Statement st;
private ResultSet rs;
public SQLConnect() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname?zeroDateTimeBehavior=convertToNull", "root", "");
st = con.createStatement();
} catch (ClassNotFoundException | SQLException ex) {
System.out.println("Error in constructor: " + ex);
}
}
//this method gets called before I make another query
public void reconnect() {
try {
st.close();
con.close();
if (con.isClosed()) {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname", "root", "");
st = con.createStatement();
}
} catch (SQLException ex) {
Logger.getLogger(SQLConnect.class.getName()).log(Level.SEVERE, null, ex);
}
}
//sample method on how I do queries
public ResultSet getMemberViaMemberId(String mID) {
try {
String query = "CALL getMemberViaMemberId(" + mID + ");"; //procedure call
rs = st.executeQuery(query);
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
return rs;
}
}//end of class
The way I call it in my JForm is this..
SQLConnect connect;
public Class(){
connect = new SQLConnect();
}
public void methodThatGetsCalledALot(String current_id){
connect.reconnect(); //refer to SQLConnectClass displayed above
ResultSet member = connect.getMemberViaMemberId(current_id);
try{
if (member.next()) {
lastName = member.getString("last_name");
firstName = member.getString("first_name");
}
//display data...
} catch (SQLException ex){
}
}
The code:
connect.reconnect();
ResultSet rs = connect.callSQLMethod();
is the most essential bit and is called by every class, and by every method that needs to fetch data. I have to acknowledge that I never bother closing ResultSet because often times it's inside a loop and gets replaced with new data anyway.
Again, my problem is: I cant continue fetching data anymore because of too many connections. Am I really closing things properly or am I missing something? Any suggestions on how to fix this? If my question is too confusing, I'd add more details if required. Thank you. If anyone's to keen on freely helping me out, I'd go for some emailing. Thank you! And Happy New Year btw.
You seem to be creating a lot of connections and recursing with the ResultSet open. Don't create new connections all the time, all you need is one connection and don't reconnect all the time. You actually don't need the reconnect method at all (unless you connection closes automatically, in which case you can check if it is closed before executing query). And you need to close the ResultSet once you are done retrieving values.
All you need is the data and not the resultset. So take the data and release the resource ie ResultSet. So do this -
In your getMemberViaMemberId don't return ResultSet, in that method itself, iterate through the resultset and create the object for the row and store it into a collection and return that collection after closing the ResultSet. And dont call reconnect method at all.
Close the single connection that you have when exiting the program.

Java memory leak caused by MySQL libraries

I have a thread that executes and updates a database with some values. I commented out all the operations done to the data and just left the lines you can see below. While running the program with the lines you see bellow I get a memory leak.
This is what it looks like in VisualVM
Mysql Class
public ResultSet executeQuery(String Query) throws SQLException {
statement = this.connection.createStatement();
resultSet = statement.executeQuery(Query);
return resultSet;
}
public void executeUpdate(String Query) throws SQLException {
Statement tmpStatement = this.connection.createStatement();
tmpStatement.executeUpdate(Query);
tmpStatement.close();
tmpStatement=null;
}
Thread file
public void run() {
ResultSet results;
String query;
int id;
String IP;
int port;
String SearchTerm;
int sleepTime;
while (true) {
try {
query = "SELECT * FROM example WHERE a='0'";
results = this.database.executeQuery(query);
while (results.next()) {
id = results.getInt("id");
query = "UPDATE example SET a='1' WHERE id='"
+ id + "'";
SearchTerm=null;
this.database.executeUpdate(query);
}
results.close();
results = null;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The problem has happened with many other people after researching the web,
https://forum.hibernate.org/viewtopic.php?f=1&t=987128
Is bone cp or mysql.jdbc.JDBC4Connection known for leaking?
and a few more if you google "jdbc4resultset memory leak"
The leak is yours, not MySQL's. You aren't closing the statement.
The design of your method is poor. It should close the statement, and it should return something that will survive closing of the statement, such as a CachedRowSet.
Or else it should not exist at all. It's only three lines, and it doesn't support query parameters, so it isn't really much use. I would just delete it.
You also appear to have statement as an instance member, which is rarely if ever correct. It should be local to the method. At present your code isn't even thread-safe.
You should also be closing the ResultSet in a finally block to ensure it gets closed. Ditto the Statement.
Make sure that you are explicitly closing the database connections.

Strange problem with JDBC, select returns null

I am trying to use JDBC and my query is working in some cases but not working in others.
I would really appreciate any help.
Some of my code:
public Result getSpecificTopic()
{
String query = "Select msg_body, msg_author from lawers_topic_msg";// where msg_id=2 order by msg_id desc";
try
{
con = mysql.getConnection();
//Statement stmt = con.createStatement();
PreparedStatement stmt = con.prepareStatement(query);
//stmt.setInt(1, topicId);
ResultSet rs = stmt.executeQuery(query);
int rowCount = rs.getRow();
specificTopic = ResultSupport.toResult(rs);
con.close();
stmt.close();
}
catch(Exception e)
{
}
return this.specificTopic;
}
public void setTopicId(String num)
{
this.topicId = Integer.parseInt(num);
}
public int getTopicId()
{
return this.topicId;
}
However if i change
String query = "Select msg_body, msg_author from lawers_topic_msg";
to the
String query = "Select msg_body, msg_author from lawers_topic_msg where msg_id = " + topicId;
Then the resultset retunrs nothing....
I am breaking my head here and still cannot figure out what is the problem
You still aren't closing your resources properly. That should be done in a finally block:
http://www.java-blog.com/correct-closing-jdbc-resources
As a first step, it'd be worth making sure an exception's not being thrown - at the very least log something in your catch() block.
Also be worth logging the SQL generated, and making sure that actually returns what you expect from the database when running it directly.
If you have multiple databases, it'd be worth confirming you're running against the one you think you are - I'm embarrassed to admit I've been caught out that way before.
several issues with your code, i'll keep it short:
don't encapuslate with try / catch at this layer, aspecially not since you're doing no error management. this.specificTopic looks global, so if your query fails it will return whatever was stored in this.specificTopic.
also try what BobbyShaftoe said. print in console or use your debugger. This should give you a good indication on what is wrong.
my first guess would be Integer.parseInt(num) could throw an exception. if so, the sql statement will be broken.
secondly, as Makach pointed out, there are several issues. first the catch-all
you should not use string concatenation, like
....where msg_id = " + topicId;
but rather
....where msg_id = ?"
stmt.set Int(1,topicId)
edit: it seems thats what you were trying anyways, SO sucks in some characters.

Categories

Resources