Search code examples
javajdbcdatabase-connectiondatasourceconnection-pooling

Is it necessary to get a a new Datasource from JNDI for every connection?


Looking at answers from high reputation users such as this it seems that it's appropriate to get a new DataSource object by querying the JNDI naming service on every single connection request. E.g. with code like the following (adapted from the linked answer for more brevity):

public class ConnectionManager{
       public static Connection getConnection() throws NamingException {
            Context initContext  = new InitialContext();
            Context envContext  = (Context)initContext.lookup("java:/comp/env");
            DataSource dataSource = (DataSource)envContext.lookup("jdbc/test");
            return dataSource.getConnection();
       }
}

Is this really, the suggested / idiomatic way? In some of my own "ConnectionManager" utilty classes I used to keep a reference to the DataSource object as an instance variable. Nothing wrong came out of it except when the JBoss administrator disabled and enabled the connection pool from the admin console and then my code was getting errors like the following:

java.sql.SQLException: javax.resource.ResourceException: IJ000451: The connection manager is shutdown

So, is it an anti-pattern to keep around instances of DataSource objects in JDBC?


Solution

  • A DataSource object can be cached and is thread-safe, although JNDI ought to be well-enough optimized that getting the DS out of JNDI every request is negligible (the same instance will be handed back from JNDI).

    If you're working in a Java EE environment for example, it's spec standard to be able to inject a DataSource at the class level, such as:

    public class MyServlet extends HttpServlet {
    
      @Resource
      DataSource ds;
    
      public void processRequest() {
        try(Connection con = ds.getConnection()) {
          // ...
        }
      }
    
    }
    

    Also, it's completely safe to share DataSource objects across multiple threads. On the other hand, sharing Connection objects across multiple threads is a big mistake, because those are NOT threadsafe per spec.