I try to insert a row to the database, but it doesn't appear in the table after running:
This is the main class:
public class Tester {
public static void main(String[] args) {
CouponsDbDao coupDbDao = new CouponsDbDao();
Coupon coupon = new Coupon(1, 0, Category.Food, null, null, null, null, 25, 0, null);
coupDbDao.addCoupon(coupon);
}
}
And this is the method:
public class CouponsDbDao {
public void addCoupon(Coupon coupon) {
try {
Connection connection = JdbcUtils.getConnection();
String sqlStatement = "insert into coupons (COMPANY_ID,CATEGORY_ID,TITLE,DESCRIPTION,START_DATE,END_DATE,AMOUNT,PRICE,IMAGE) values(?,?,?,?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sqlStatement);
statement.setInt(1, coupon.getCompanyId());
statement.setObject(2, coupon.getCategory());
statement.setString(3, coupon.getTitle());
statement.setString(4, coupon.getDescription());
statement.setDate(5, coupon.getStartDate());
statement.setDate(6, coupon.getEndDate());
statement.setInt(7, coupon.getAmount());
statement.setDouble(8, coupon.getPrice());
statement.setString(9, coupon.getImage());
} catch (Exception e) {
e.printStackTrace();
}
}
You need to execute the statement after setting values. Additionally, you need to close the connection created, the preparedstatement etc in a finally block.
public class CouponsDbDao {
Connection connection = null;
PreparedStatement statement = null;
public void addCoupon(Coupon coupon) {
try {
connection= JdbcUtils.getConnection();
String sqlStatement = "insert into coupons (COMPANY_ID,CATEGORY_ID,TITLE,DESCRIPTION,START_DATE,END_DATE,AMOUNT,PRICE,IMAGE) values(?,?,?,?,?,?,?,?,?)";
statement = connection.prepareStatement(sqlStatement);
statement.setInt(1, coupon.getCompanyId());
statement.setObject(2, coupon.getCategory());
statement.setString(3, coupon.getTitle());
statement.setString(4, coupon.getDescription());
statement.setDate(5, coupon.getStartDate());
statement.setDate(6, coupon.getEndDate());
statement.setInt(7, coupon.getAmount());
statement.setDouble(8, coupon.getPrice());
statement.setString(9, coupon.getImage());
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
finally{
if (statement != null) {
try {
statement.close();
} catch (SQLException e) { /* print here */}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) { /* print here */}
}
}
}
As told by others you need to call executeUpdate to really perform the query:
Executes the SQL statement in this PreparedStatement object, which must be an SQL Data Manipulation Language (DML) statement, such as INSERT, UPDATE or DELETE
I suggest you also to use the try with resources:
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
This has been introduced in java 7 and let you eliminate the finally boiler plate code as follow:
// ORIGINAL CODE
Connection connection = ...
try {
connection = JdbcUtils.getConnection();
...
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) { /* print here */}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) { /* print here */}
}
}
becomes:
// USING try with resources
try (Connection connection = JdbcUtils.getConnection()) {
...
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} // NO need of the finally block because connection is AutoCloseable
You need to execute update for statement, like:
statement.executeUpdate();
I am trying to see the vulnerability of my code with fortify. The report said that I have an issue which said "the function sometimes fails to release a database resource allocated by". Here is the code and in which line the issue pointed. I've tried to close the connection in the finally block but it not solve the issue. How to fix this?
private AnotherService anotherService;
private void create() {
Connection conn = null;
try {
conn = getCon(); // With fortify, there's an issue which said "the function sometimes fails to release a database resource allocated by", and it refers to this line
conn.setAutoCommit(false);
anotherService.myFunction(conn);
// the conn.commit() is inside anotherService, because I have to make one connection
// rest of code
} catch (Exception e) {
e.printStackTrace;
if (null != conn) {
conn.rollback();
}
} finally {
if (null != conn) {
conn.close();
}
}
}
private static Connection getCon() {
Connection connection = null;
try {
Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/dbname",
"username",
"password");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
Addition:
If I use try-with-resource (like this try (Connection conn = getCon()), to automatically close things, how I could call conn.rollback() in the catch block if any exception occured? Since the conn variable declared inside the try-with-resources.
Well, I solve my problem, the close method should call inside try-catch in the finally block, as mentioned in this link.
In case the link broken, here is the code that I use to solve my problem:
Statement stmt = null;
ResultSet rs = null;
Connection conn = getConnection();
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(sqlQuery);
processResults(rs);
} catch (SQLException e) {
// Forward to handler
} finally {
try {
if (rs != null) {rs.close();}
} catch (SQLException e) {
// Forward to handler
} finally {
try {
if (stmt != null) {stmt.close();}
} catch (SQLException e) {
// Forward to handler
} finally {
try {
if (conn != null) {conn.close();}
} catch (SQLException e) {
// Forward to handler
}
}
}
}
Useful piece of code for Hive JDBC:
Connection con = null;
Statement stmt = null
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
con = DriverManager.getConnection(connectionUri, userName, password);
stmt = con.createStatement();
stmt.executeUpdate(query);
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I want to remove try - catch in finally block.
So I tried The try-with-resources Statement.
try (Class.forName("org.apache.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();){
stmt.executeUpdate(query);
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
I think this is not the right way.
Class.forName("org.apache.hive.jdbc.HiveDriver") should not be in try. Should I make a separate try-catch for this?
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
} catch (ClassNotFoundException cex) {
cex.printStackTrace();
}
try (Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();){
stmt.executeUpdate(query);
} catch (SQLException e) {
e.printStackTrace();
}
Is this right way or am I missing any thing?
The idea behind try-with-ressource is to close an AutoCloseable class.
So every usage of a class which should be closed after using it (a Ressource) can be used with try-with-ressource (like Connection for example). You don't have to take care of closing it manually (in an finally block for example).
So yes, your idea is right:
try/catch for Class.forName("org.apache.hive.jdbc.HiveDriver"); - because this is not AutoCloseable
try-with-ressource for Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement();- because Connection and Statement implement AutoCloseable
Reference:
https://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html
When you're using Java 6 or better and the Apache Hive JDBC driver is JDBC 4 compliant or better* then you do not need the Class.forName("org.apache.hive.jdbc.HiveDriver") stuff at all.
Therefore you can just remove the entire try/catch block from your second solution and you're good to go with just:
try (Connection con = DriverManager.getConnection(connectionUri, userName, password);
Statement stmt = con.createStatement()) {
stmt.executeUpdate(query);
} catch (SQLException e) {
e.printStackTrace();
}
* Which is the case for version 1.2.0 or newer of the Hive JDBC driver
I'm trying to figure out how to rollback commits from multiple methods. I want to do something like the following (editing for brevity)
public void testMultipleMethodRollback() throws DatabaseException {
Connection conn = connect();
fakeMethodRollback1();
fakeMethodRollback2();
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
and currently all my methods are formatted like this
public void fakeMethodRollback1() throws DatabaseException {
Connection con = connect();
PreparedStatement ps = null;
ResultSet rs = null;
// insert some queries
try {
String query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
con.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
throw new DatabaseException(e);
} finally {
close(rs, ps, conn);
}
}
because I want to be able to use the other methods independently, how can I do a rollback where if one method fails, the others will roll back? I fear I have my whole class setup wrong or at least wrong enough that this can't be accomplished without major work. I can't change the methods to return a connection, because half of my methods are get methods, which are already returning other data. Any ideas?
In the following code snippet,
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore){}
}
what happens when an exception occurs in the finally block while executing stmt.close();.
Is there a better way to handle these kind of problems?
sometimes connections is not open because of some exception but finally block close that connection. To avoid this Exception check out following code.
try{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}catch(SQLException e){
//handle exception
}finally{
try{
if(stmt != null){
stmt.close();
}
}
catch(SQLException ignore){}
}
finally
{
if( stmt != null ) {
try {
stmt.close();
}
catch(SQLException ex ) {
ex.printStackTrace();
}
}
}
Problems which might occur is that a statement isn't closed and then you will get an error when trying to reuse it.
try:
Statement stmt = null;
try {
stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e) {
//handle exception
}
finally
{
try{ if(stmt!=null)stmt.close(); }
catch(SQLException ignore){}
}
Usually when an exception occur we wrap it over our User defined exception and throw.
Similarly u need to throw ur own exception, when an exception occurs in finally also.
try
{
Statement stmt = conect.getConnection();
stmt.executeUpdate(query);
}
catch(SQLException e)
{
//handle exception
throw MyOwnException(e,"My message");
}
finally
{
try{ stmt.close(); }
catch(SQLException ignore)
{
throw MyOwnException(ignore,"My message");
}
}