0

I'm writing some Java application that uses Java DB (i.e. Apache Derby) as database. I use the following method to connect to database:

Connection getConnection() throws SQLException {

        EmbeddedDataSource  ds =  new EmbeddedDataSource();
        ds.setDatabaseName(dbUri);
        ds.setPassword(password);
        ds.setUser(username);

        Connection conn = ds.getConnection();               
        conn.setSchema(schema); 

        return conn;            
    }

This works ok, but sometimes I get the following exception:

java.sql.SQLException: Another instance of Derby may have already booted the database

This happens when I run my application and at the same time SQuirreL SQL Client is connected to my database. So everything works as expected, but I would like to be able to check for this in my getConnection() method. I other words, I would like to check if any sessions are opened to my database, and for example, close them, throw my own exception or display error dialog box. I don't know how to do this.

Thx

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Marcin
  • 215,873
  • 14
  • 235
  • 294

3 Answers3

0

Rather than declaring that your application "throws SQLException", you can use a "try" block to catch the SQLException, then examine the exception and decide if it is the "Another instance of Derby" exception or not.

Then, you can throw your own exception from your "getConnection" method accordingly.

Bryan Pendleton
  • 16,128
  • 3
  • 32
  • 56
0

I modified my getConnection() method to something like below. It does what i want:

  Connection getConnection() throws SQLException, DAOConnection {

        EmbeddedDataSource  ds =  new EmbeddedDataSource();
        ds.setDatabaseName(dbUri);
        ds.setPassword(password);
        ds.setUser(username);

        Connection conn = null;

        try {
            conn = ds.getConnection();
        } catch (SQLException e) {          

            // check if cannot connect due to "Another instance of 
                    // Derby may have already booted the database".
                    // The error code of this exception is 45000.

            if (e.getNextException().getErrorCode() ==  45000) {
                throw new DAOConnection(e.getNextException().getMessage());
            } 

            throw new SQLException(e);
        }

        conn.setSchema(schema);                         
        return conn;            
    }
Marcin
  • 215,873
  • 14
  • 235
  • 294
0

Prevention is better than cure. IMO, catching exception and then realizing it was duplicate Derby server started is not an ideal design. Better would be to prevent duplicate instantiation. If possible you can synchronize your getConnection() method or make it part of a singleton class or load the embedded Derby driver from static initializer block of a startup/main class which is loaded only once by JVM and hence Derby will be started only once. Something like following in the main/startup class should do the trick:

static {
   try {
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); 
   }
   catch(Exception e){
    .....
   }
}

Per the link here http://db.apache.org/derby/docs/10.3/devguide/tdevdvlp38381.html loading the Driver should start the Derby embedded system.

Bimalesh Jha
  • 1,464
  • 9
  • 17