1

I have a DAO class which have many methods manipulating the database. I am using one connection object for all methods like this (Database.connect() returns a connection object):

class ExampleDAOImpl implements ExampleDAO{
  private Connection con = null;

  public void method1 () {
   con = Database.connect();
   ....
   con.close();
  }

  public void method2 () {
   con = Database.connect();
   ....
   con.close();
  }

 public void method1 () {
   con = Database.connect();
   ....
   con.close();
  }
}

Is this a good practice to instantiate a new connection for each method and close it? I am having now errors saying " No operations allowed after connection closed" Although I am initializing the connection at the beginning of each method and closing it at the end. Or it's better to use the same connection object and have a separate method which closes it when i call it?

4
  • 3
    If these methods call each other, the inner call will prematurely close the connection and thereby cause the error you're seeing. Commented Jun 18, 2012 at 11:46
  • You have to provide more details about the exception! StackTrace or Line Number for example would be helpful! Commented Jun 18, 2012 at 11:54
  • possible duplicate of JDBC Best practice Commented Jun 18, 2012 at 12:53
  • Or it's better to use the same connection object - try it. If you use database during whole lifecycle of your program, open connection when program started and close on exit. Commented Jun 18, 2012 at 13:58

7 Answers 7

2

Objects of class ExampleDAOImpl are not thread-safe. So if more than one thread use the same ExampleDAOImpl object and call methods at the same time, it could happen that one closes the connection then the other thread tries to use it.

Possible solutions:

  • Ensure that the ExampleDAOImpl Objects are never used in multi-threaded context. This will be still error-prone.
  • Better suggestion: instead of using a single Connection Object, use a ConnectionPool to get a connection at the beginning of each method and free it after you finish from it.
Sign up to request clarification or add additional context in comments.

Comments

0

What the point of making a global connection when you opening connection in each method. This is likely waht happening when you call method2 from method1 it closes connection that is used by method1

Generally the good practice is to create connection once in application life and close the connection on application close/exit, as there is cost of opening and closing connection.

1 Comment

then how can you determine when to close the connection? Or, can you give an example of such a safe exit?
0

your codes are not thread-safe, because jdbc connection can not be used concurrently! Please Change Connection con to a ThreadLocal, and add two methods to connect and disconnection.

The codes will be like:

public class ConnectionHelper
{
private static ThreadLocal<Connection> con = new ThreadLocal<Connection>();

protected Connection getConnection()
{
if(con.get() ==null)
{
con.set(Database.connect());
}
return con.get();
}

protected Connection closeConnection()
{
if(con.get() !=null)
{
con.get().close;
}
}
}

in your DAO: public void method1 () { try { Connection con = ConnectionHelper.getConnection(); } finally { ConnectionHelper.closeConnection(); } }

2 Comments

Does this provides synchronization?
you don't need synchronization for a ThreadLocal, it's a variable in Thread scope.
0

create two function one for

  connection()

another for

  disconnection()

call those methods in every method

  function method()
 {
  //call 

  connection();

  //code;

  //call 

     disconnection();
  } 

Comments

0

If you are using a Connection Pool implementation like BoneCP, it is perfectly fine to open new connections for each method, just ensure that the method does not reference the instance variable, but rather a local variable.

On the other hand if you have no connection pool available and working with only one connection, you will have to find a suitable place to close that connection, since getting new ones without a pool is quite expensive.

Comments

0

If what you want is to DRY your code, then use abstract classes and lambdas

class ExampleDAOImpl implements ExampleDAO{

    // With lambdas
    public void method1 () {
       withConnection( (Connection con) -> {
           // do whatever you want with the connection
           // no need to open or close it
       })
    }

    // Old style abstract class
    public void method2 () {
       withConnection(new TaskExecutor(){
          void doStuff(Connection con){
             // do whatever you want with the connection
             // no need to open or close it
          }
       })
    }

    // This is the magic you have to add.
    private void withConnection(TaskExecutor executer){
        // Instantiate it to avoid race conditions
        // good thing this is the only place
        // you have to worry about opening and closing it
        Connection con = Database.connect();
        executer.doStuff(con);
        con.close();
    }

    private abstract class TaskExecutor{
        abstract void doStuff(Connection con);
    }

}

Comments

0

I solved my own problem with creating one connection for all methods :

 public void generateTestData() throws SQLException, ClassNotFoundException, IOException {
    ConnectionToDatabase connectionToDatabase = new ConnectionToDatabase();
    try (Connection connection = connectionToDatabase.connectToDatabase()) {
        {
            generateGroups(connection);
            generateCourses(connection);
            assignCoursesToStudents(connection);
        }
    }
}

Maybe for smb it will be useful :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.