Question

I have a javax.sql.DataSource that I want to use in multiple servlets. I don't like the idea of specifying:

@Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
private DataSource liveDataSource_;

in every servlet as it seems to me that the framework will have to be looking up the DataSource for every servlet and if the name of the DataSource changes, every servlet will have to change too.

My idea is to declare a Singleton EJB that can then be declared in each servlet:

@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class DataSources {  
    @Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
    private DataSource liveDataSource_;

    public synchronized Connection getLiveConnection() throws SQLException {
        return liveDataSource_.getConnection();
    }
}

Is this a reasonable way of solving the issue? I feel it's a bit heavy handed for something I would have thought would be a common issue.

Was it helpful?

Solution

In general it's ok IMO. But please don't let the bean return the connection but directly the DataSource. Some AppServers like WebSphere will automatically close the connection when the bean context is left again.

Another solution would be to use @Resource(name="myds") instead of lookup. If all your Servlets are in one Web Application then you can define one resource-ref with res-ref-name myds in your web.xml and resolve it to the real lookup name only at that place.

OTHER TIPS

I'd say that using an EJB only for that reason may be a bit too heavy as you wrote.

First most of modern application servers will cache that lookup so it will not be that costly.

Second - you can use @Resource(name="myds") as Robert said which would use same resource reference, that can be mapped to the JNDI name using application server's mapping functions.

Third - you could use CDI to have web module only solution like this:

Create class which hold your DataSource definition like this:

public class Datasources {

    @Produces @Resource(name="jdbc/yourRef", lookup="yourJNDI")
    DataSource myDataSource;
}

And then use it servlet using Inject:

public class MyServlet extends HttpServlet {
    @Inject 
    private DataSource myDs;   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top