Liam Bull
Liam Bull

Reputation: 51

Java using JDBC - Too many connections?

I am writing a stock replenishment system for a bar as my final year project. I can retrieve information from a MYSQL database and I can scroll through one result at a time.

I'm trying to change the results depending on a selected category. I've managed to use a combo box to acheive this but I get the following error when moving between categories:

Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"

The code for the two separate files are as follows:

If anyone can help it would be appreciated.

Upvotes: 5

Views: 33799

Answers (3)

ugo
ugo

Reputation: 2696

I think I see the problem in your code. Your code is extremely strange but here's what I think is happening:

In your ViewStockQuery class, you have the retrieveStock() method. This method then creates an instance of your GUI class, ViewStockGUI. Apart from this being bad practice, it leads to a problem here because in the constructor of the ViewStockGUI, which you called in the retrieveStock() method in this line:

stockGUI = new ViewStockGUI();

you then again call retrieveStock() with this line:

final ViewStockQuery stock = new ViewStockQuery();

comboGUI = stock.getComboBox();
stock.retrieveStock();

This leads to a recursive issue as your ViewStockGUI() constructor calls the retrieveStock() method which creates a connection and again calls the ViewStockGUI() constructor which will again call the retrieveStock() method that hasn't closed the connection and tries to open a different connection. Hope you get the picture.

A way to solve it is to clean up your code. Don't call the constructor in retrieveStock(). Find a different way to pass the selected category for your query.

Edit:

Write you ViewStockQuery like so:

private String mSelected;

public ViewStockQuery(String selectedCategory) {
    mSelected = selectedCategory;
}

...

public void retrieveStock() throws SQLException { 

    con = SQLConnect.getConnection();


    String viewStock = "SELECT * FROM Stock where categoryName = '" + "'" + mSelected + "'";
    System.out.println(viewStock);


     try {
...

Then write your ViewStockGUI in such a way that when a category has been selected, that is when you create the ViewStockQuery and pass in the selected string.

Edit:

Like I said before, there are quite a lot of things you will eventually need to change in your code. But, for the purpose of this issue, what you could do is in your ViewStockGUI, do:

String selected = (String)combo.getSelectedItem();
final ViewStockQuery stock = new ViewStockQuery(selected);

The first line collects the selected category from your combobox and the second line creates an instance of ViewStockQuery and passes the selected to the constructor. This will then initialize mSelected as you see in the constructor I put above for ViewStockQuery.

Upvotes: 1

Puce
Puce

Reputation: 38132

If you want to use JDBC (rather than JPA), then I recommend to either use JdbcTemplate from Spring or the Automatic Resource Management (ARM) of Java SE 7. (I haven't tried JDBC with ARM yet, but it should work.)

Basically, you need to close Closeables in the finally blocks of a try-catch clause.

Upvotes: 0

Cratylus
Cratylus

Reputation: 54074

You get this exception when you have too many open connections.
This is configurable but in your case the problem is in your code.

The code you posted is weird (the least).
You either don't close the connection unless you get an SQLException or you close it during processing of a result set!

In any case you should refactor your code to close connections and result set etc as soon as you are finished.
Example:

try { 

     stat = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE ); 
     rs = stat.executeQuery("SELECT categoryName FROM Category"); 

  while (rs.next()) { 
      combo.addItem(rs.getString("categoryName")); 
      categoryName = rs.getString("categoryName");  


  } 
} catch (SQLException sqle) { 
  System.out.println(sqle);   
} 
finally{
 if(stat != null) stat.close(); 
 if(con != null)  con.close(); 
}

By putting the close in a finally you are sure that the connection is closed either in correct flow or in exception (I have omitted try-catch for clarity).

So modify the code this way to close the connections.

For better performance you should look into connection pooling

Upvotes: 7

Related Questions