I started learning databases in java with postgres. I created database and now need to add there some data. I can add data succesfully only one time, then i get SQLException and can't add anything to database, so i need to launch my project again. Where did i go wrong?
Here is method for adding: (if its not enough, i can add what is needed)
public final Connection CONNECTION = DriverManager.getConnection
(url, login, pass);
public void sqlAddData(Algorithm codec, String input, String translated) throws SQLException {
try (CONNECTION) {
java.sql.Timestamp date = new java.sql.Timestamp(new java.util.Date().getTime());
String add = " insert into db.public.history ( codec, input, translated, date) values(?,?,?,?)";
PreparedStatement prepared = CONNECTION.prepareStatement(add);
prepared.setString(1, String.valueOf(codec));
prepared.setString(2, input);
prepared.setString(3, translated);
prepared.setTimestamp(4, date);
prepared.executeUpdate();
} catch (SQLException e) {
logger.warning("Error with database");
}
CONNECTION.close();
}
Thanks for help and i'm sorry, if it is noob question, i'm just learning.
Its because you close the connection after one call.
CONNECTION.close(); is the last thing you do and that closes the connection, if u wanna add data again you need to open the connection once again, or wait to close when you dont wanna add anything more.
In your code you instantiate your connection before your method with :
public final Connection CONNECTION = DriverManager.getConnection(url, login, pass);
Which means, if you close it inside your method you will not be able to reuse this connection unless you create a new one (instantiate a new one).
To fix your problem here is what you can do :
public final Connection CONNECTION;
public void sqlAddData(Algorithm codec, String input, String translated) throws SQLException {
CONNECTION = DriverManager.getConnection(url, login, pass);
try (CONNECTION) {
java.sql.Timestamp date = new java.sql.Timestamp(new java.util.Date().getTime());
String add = " insert into db.public.history ( codec, input, translated, date) values(?,?,?,?)";
PreparedStatement prepared = CONNECTION.prepareStatement(add);
prepared.setString(1, String.valueOf(codec));
prepared.setString(2, input);
prepared.setString(3, translated);
prepared.setTimestamp(4, date);
prepared.executeUpdate();
} catch (SQLException e) {
// Handle your exception correctly or throw it.
}
}
Note you can also use try-catch-finally to safely close your connection. I didn't show you how to catch your exception I will let you do some digging yourself ;)
Also note that you are using try-with-resources which remove the finally block and still close your connection safely.
Hope this helps.
The reason you can only connect to the database one time is because you're closing the open connection by wrapping the Connection object in a try-with-resources statement. Also, you're calling close on Connection after that statement which is redundant.
A solution to this problem would be to use connection pooling. Some good options are Hikari and C3P0.
Related
Okay I executed the same code thats in the update query in the SQLite db browser and it worked successfully
public void StatusUpdate(ActionEvent event) {
try {
String test = null;
test = txtEditStatus.getText();
System.out.println(test);
String query = "UPDATE member SET desc = ? WHERE username = ?";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString (1, test);
preparedStmt.setString(2, "Custom Hue");
// execute the java preparedstatement
preparedStmt.executeUpdate();
connection.close();
} catch (Exception e) {
}
However when running eclipse with JFx, it prints what I type in the console but doesnt update in the db, anyone know why?
For the user asking about the connection:
Connection connection;
public ProfileController() {
connection = SQLConnection.Connector();
if (connection == null)
System.exit(1);
}
I would check that your connection is actually connected to the correct database.
are you sure you have the right connection string set up?
you should do an output on your exception handler, what if there is an exception?
are you sure the connection is open?
are you sure the user exists in the database and table you are trying to update?
try doing a read first, to see if you have an open connection. Print your exception, just in case, never leave it blank. That's just bad practice.
How about you try a
preparedStmt.executeUpdate();
connection.commit();
connection.close();
Just incase autocommit isn't enabled?
I'm using OJDBC(v7) to connect to Oracle(11g), in Java.
In some cases on some big tables, the Resultset can not fetch the data in appropriate time.
For example the output records are just 2, but on the Resultset.next() java freezes and waits too long!
Note1: The problem is not about setting FetchSize(), RsultSet.TypeX , not using connection pools like c3p0 , ... . I've tested all of those.
Note2: Also when I run the query directly in navicat, the result is shown perfectly!
Getting connection method:
public Connection getDBConnection() throws DBConnectionException {
Connection conn = null;
String connectionUrl;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:user/pass#xxx.xxx.xxx.xxx:1521:DBNAME");
} catch (Exception e) {
e.printStackTrace();
throw new DBConnectionException();
}
return conn;
}
connectiong to DB part:
...
conn = connectionManager.getDBConnection();
conn.setAutoCommit(false);
String query = "{call ...(...)}";
CallableStatement stmt = conn.prepareCall(query,ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(10000);
.
.
.
stmt.registerOutParameter(x, OracleTypes.CURSOR);
stmt.execute();
Resultset rs = (ResultSet) stmt.getObject(x);
while (rs.next()) { /** Problem occurs here **/
...
}
WHY?!
use in try catch block:
if ((cnn==null)||cnn.isClosed()){
cnn=DB.getDBConnection(); //e.g. DB is instance of class where getDBConnection() resides
}
Then call queries. I believe somewhere in your code either you are closing connection or connection is becoming null that's why you are facing this problem.
Cheers
I am working on my first Java Project with MySQL. I have one function that gets called every time I get data back from my data source. This function should save a new line to my MySQL database. See the code here:
import java.sql.*;
import java.util.Properties;
/**
*
* #author jeffery
*/
public class SaveToMysql {
// The JDBC Connector Class.
private static final String dbClassName = "com.mysql.jdbc.Driver";
private static final String CONNECTION = "jdbc:mysql://localhost/test";
static public String test(int reqId, String date, double open, double high, double low,
double close, int volume, int count, double WAP, boolean hasGaps){
if (date.contains("finished")){
return "finished";
}
// Class.forName(xxx) loads the jdbc classes and
// creates a drivermanager class factory
try{
Class.forName(dbClassName);
}catch ( ClassNotFoundException e ) {
System.out.println(e);
}
// Properties for user and password. Here the user and password are both 'paulr'
Properties p = new Properties();
p.put("user","XXXXXXXX");
p.put("password","XXXXXXXXXXXx");
// Now try to connect
Connection conn;
try{
conn = DriverManager.getConnection(CONNECTION,p);
}catch(SQLException e){
return e.toString();
}
PreparedStatement stmt;
try{
stmt = conn.prepareStatement("insert into dj_minute_data set symbol = (select ticker from dow_jones_constituents where id = ?), "
+ "date = str_to_date(?,'%Y%m%d %H:%i:%s')" +
", open = ?" +
", high = ?" +
", low = ?" +
", close = ?" +
", volume = ?" +
", adj_close = ?");
stmt.setInt(1, reqId);
stmt.setString(2, date);
stmt.setDouble(3, open);
stmt.setDouble(4, high);
stmt.setDouble(5, low);
stmt.setDouble(6, close);
stmt.setDouble(7, volume);
stmt.setDouble(8, WAP);
}catch (SQLException e){
return e.toString();
}
try{
stmt.executeUpdate();
}catch (SQLException e){
return e.toString();
}
return stmt.toString();
}
}
As you all can see this function test is in its own class, called SaveToMysql. To call this function, I import the class into a different class, and use this syntax:
msg = SaveToMysql.test(reqId, date, open, high, low, close, volume, count, WAP, hasGaps);
The msg then get output to the screen. Showing either error message or success.
This function may be called many times rapidly in a short time period. I know I should not have to re-open my connection with the MySQL server every time the function gets called. How would I change this so that the 1 MySQL connection stays open for every call to the function.
Thanks!!
JDBC URL: jdbc:mysql://:/? connectTimeout=0&socketTimeout=0&autoReconnect=true
I know I should not have to re-open my connection with the MySQL server every time the function gets called.
No, it's fine to do so - as long as you have a connection pool under the hood to manage the real connections. There are various connection pool projects around, such as c3p0 and DBCP. That way you can make each of your calls isolated from the others:
Fetch a connection from the pool
Use it
Release it back to the pool
See the documentation for whichever pool you choose for the details. Often connection pools allow you to just request a connection from JDBC as normal and then close it as normal, effectively making the whole thing transparent.
Also note that you should definitely start using prepared statements with parameters rather than including your values directly in your SQL statement. Your current code is a SQL injection attack waiting to happen.
you need to manage one static class or method.
like
public class ConnectionClass
{
public static Connection connection = null;
public Connection getCurrentConnection()
{
if(connection != null)
{
return connection;
}
else
{
create new connection...
and return that new connection after giving it to global connection..
}
}
}
by this every time you will get current connection. and if there is some issue and connection is not available then you can create new connection. when you need connection object you just need to call getCurrentConnection method.
so you just need to following things in ur code.
Connection conn;
try{
//conn = DriverManager.getConnection(CONNECTION,p);
conn = getCurrentConnection();
}catch(SQLException e){
return e.toString();
}
If you want use 1 connection when call SaveToMysql.test method many times, you can add your connection in method parameter, or create a global connection variable out side SaveToMysql.test method. but, if you use 1 connection, please attention about transaction. I hope it will help you.
I have written the following java code to connect the Oracle Express Edition database.....I have read a lot about closing the connection, statement and result but there are some questions about this issue...
1- I usually test my code several time so If I Don not close the connection and etc. will I face with any problem?!!(because the connection is made on the same variable or object in my code!!!!)
2-how can I understand how many connections exist now?(after testing the code for several time)
3- Should I place CLOSE methods in finally block with a new TRY CATCH block or add THROWS SQLException after main method?!!!! what is the difference between these to implementation?!!!
package mainAssignment;
import java.sql.*;
import java.text.MessageFormat;
import java.math.*;
import java.util.*;
//import java.text.MessageFormat;
public class Conn {
/**
* #param args
*/
public static void main(String[] args)throws SQLException{
// TODO Auto-generated method stub
String jdbcURL = "jdbc:oracle:thin:#localhost:1521:xe";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String user = "hr";
String passwd = "hr";
Scanner input = new Scanner(System.in);
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(jdbcURL, user, passwd);
System.out.println("ok");
System.out.println("Please enter the desired employee ID: ");
Object[] arg={new String(input.nextLine())};
String query = MessageFormat.format(
"select * from EMPLOYEES where employee_id={0}", arg);
//System.out.println(query);
stmt = conn.createStatement();
stmt.executeQuery(query);
rs = stmt.getResultSet();
while (rs.next()) {
BigDecimal empid = rs.getBigDecimal(1);
String firstname = rs.getString("FIRST_NAME");
System.out.println("employee ID " + empid
+ " first name is " + firstname);
}
} catch (SQLException e) {
e.printStackTrace();
// TODO
} catch (ClassNotFoundException e) {
// TODO
e.printStackTrace();
} finally {
conn.close();
rs.close();
if (conn.isClosed())
System.out.println("no connection any more");
else
System.out.println("connection exists");
}
}
}
1) You'll be left with many idle (hanging) connections after you finish the execution. To prevent that check whether the connection is null. If it is - establish a new one, if it's not null - use existing.
2) You can check it on the sql server. Example for ms sql server: How to determine total number of open/active connections in ms sql server 2005
3) Putting close methods in finally block is a good practice. Don't change that. Sometimes finally block also requires its own inner try-catch-finally block.
Side note: if you create methods that throw exceptions you're not solving any issues. it's just pushing the need to maintain the exception to the person who'll use your methods. Sometimes it's a good approach but more often it is not.
In real life applications you should also check whether the database is available, the connection was established and the query result is not null.
Appendix 1: How to check the number of active connections in oracle express:
How to list active / open connections in Oracle?
http://dbalink.wordpress.com/2008/06/08/find-active-sessions-in-oracle-database/
You may want to use a connection pool. Take a look at C3P0 or DBCP. You still need to close your result set, and statement, but when you call close on the connection it just returns it back to the pool. Update: we'be been using Hikari for connection pooling for a few years, and have been really happy with it.
I have a Java application and I want to use SQL database. I have a class for my connection :
public class SQLConnection{
private static String url = "jdbc:postgresql://localhost:5432/table";
private static String user = "postgres";
private static String passwd = "toto";
private static Connection connect;
public static Connection getInstance(){
if(connect == null){
try {
connect = DriverManager.getConnection(url, user, passwd);
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Connection Error", JOptionPane.ERROR_MESSAGE);
}
}
return connect;
}
}
And now, in another class I succeeded to print my values but when I attempt to insert a value nothing is happening ...
Here's my code :
try {
Statement state = SQLConnection.getInstance().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
Statement state2 = SQLConnection.getInstance().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
state2.executeUpdate("INSERT INTO table(field1) VALUES (\"Value\")"); // Here's my problem
ResultSet res = state.executeQuery("SELECT * FROM table");
You need to commit (and close) the connection (and statement) after use. You also need to ensure that you aren't swallowing any SQLExceptions which may cause that you see "nothing" to happen.
That said,
private static Connection connect;
This is a terribly bad idea. You should never declare external resources as static in your application. Your application will break when the other side decides to close the resource because it's been released for a too long time. You really need to acquire and close those resources (Connection, Statement and ResultSet in the shortest possible scope. I.e. inside the very same method block as where the query is to be executed.
Also, I strongly recommend to use PreparedStatement instead of Statement since that will prevent your code from SQL injection attacks.
You may find this article useful to learn more about how to do basic JDBC interaction the right way.
state2.executeUpdate("INSERT INTO table(field1) VALUES (\"Value\")");
should be:
state2.executeUpdate("INSERT INTO plateau(field1) VALUES (\"Value\")");
Copuld just be a copy over to SO error, but looking but shoulding INSERT INTO table(field1) be INSERT INTO plateau(field1)?