I feel as though I haven’t got my design right here and that I’m stuck between two techniques. I’m attempting to write a class which hands out connections to a database. The code is below:
public final class DBUtil {
private static String databaseDriver = null;
private static String databaseConnectionString = null;
private static String databaseUser = null;
private static String databasePassword = null;
private static String serverName = null;
private static ComboPooledDataSource dataSource = null;
private DBUtil() {
throw new AssertionError();
}
private static void getParameters() {
final Properties configFile = new Properties();
try {
configFile.load(DBUtil.class.getClassLoader().getResourceAsStream("my.properties"));
if (configFile.containsKey("databaseConnectionString") && configFile.containsKey("databaseUser") && configFile.containsKey("databasePassword") && configFile.containsKey("databaseDriver")) {
DBUtil.databaseConnectionString = configFile.getProperty("databaseConnectionString");
DBUtil.databaseDriver = configFile.getProperty("databaseDriver");
DBUtil.databaseUser = configFile.getProperty("databaseUser");
DBUtil.databasePassword = configFile.getProperty("databasePassword");
}
else {
// Properties file not configured correctly for database connection
}
}
catch (IOException e) {}
}
public static Connection getDatabaseConnection() {
if (Strings.isNullOrEmpty(databaseConnectionString) || Strings.isNullOrEmpty(databaseUser) || Strings.isNullOrEmpty(databasePassword) || Strings.isNullOrEmpty(databaseDriver)) {
DBUtil.getParameters();
}
dataSource = getDataSource();
int retryCount = 0;
Connection connection = null;
while (connection == null) {
try {
connection = dataSource.getConnection();
}
catch (SQLException sqle) {}
}
return connection;
}
private static ComboPooledDataSource getDataSource() {
if (dataSource == null) {
dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(databaseDriver);
dataSource.setJdbcUrl(databaseConnectionString);
dataSource.setUser(databaseUser);
dataSource.setPassword(databasePassword);
}
catch (PropertyVetoException pve) {}
}
return dataSource;
}
public static void cleanUpDataSource() {
try {
DataSources.destroy(dataSource);
}
catch (SQLException sqle) {}
}
}
FindBugs is returing Incorrect lazy initialization and update of static field when I do:
if (dataSource == null) {
dataSource = new ComboPooledDataSource();
...
Any advice greatly appreciated. I feel as though I’m stuck here somewhere between the Singleton pattern and a class which consists of simply a set of static methods.
More generally, is this a good way to hand out database connections to DAOs?
Many thanks.
That method should be
synchronizedin order to avoid two parallel executions (two threads calling it at the same time).Added
Not synchronized exception could lead to two threads executing this:
and T1 and T2 calling methods on one of two datasources (depending when T2 overrides the T1 object creation).
Volatile
As @Jean-Marc proposes you should declare datasource field as
volatile. That keyword ensures that thread don’t use a thread-local copy of the variable (that would potentially cause problems if a thread reads an outdated cached value).I’m not sure if this case happens between different method invocations, or if
syncrhonizeddeals with it but it’s better to be sure 🙂