I have an abstract PersonDao
class, extended by several other DAO classes, for example EmployeeDao
, StaffDao
.
The non-abstract DAOs correspond to different tables. The tables have some common fields, and also some unique fields. Operations on the common fields are implemented in the abstract parent PersonDao
class, operations on the unique fields are implemented in the specialized DAOs.
The parent DAO looks like this:
public abstract class PersonDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public PersonDao() {
final String tableName = getTableName();
fieldNamesCSV = getFieldNames();
String select = String.format("SELECT %s FROM %s ", fieldNamesCSV, getTableName());
}
abstract String getTableName();
abstract String getHistoricalTableName();
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
// more methods, common to all persons
}
An example specialized DAO looks like this:
public class EmployeeDao extends PersonDao {
private static final String TABLE_NAME = "EMPLOYEE";
private static final String HISTORICAL_TABLE_NAME = "EMPLOYEE_HIST";
@Qualifier("employeeDS")
@Override
public void setDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
@Override
String getTableName() {
return TABLE_NAME;
}
@Override
String getHistoricalTableName() {
return HISTO_TABLE_NAME;
}
// more methods, unique to employees
}
My question is about the code duplication in the specialized DAOs. They all have the boilerplate code of setting the data source (configured by Spring), and the overridden methods for the table names, so that the common methods in the parent class work with any table. Code quality analysis tools like Sonar detect and flag an error for these blocks.
- Do you suspect something wrong with my design that necessitates the boilerplate code? If so, please give some tips to improve it.
- If the design looks legit, do you see a way to reduce the duplication? Moving the table name constants to the methods as hard-coded strings would fool the code analysis tool, but that's hardly the solution.
- Any other tips come to mind?
UPDATE
As @pinoniq pointed out, the setDataSource
was smelly. I vaguely remembered that Spring forced me to do it that way, and differentiate the specialized classes with the @Qualifier
annotation. It seems that's not the case, I could move data source to the constructor of the specialized classes, and everything seems to work well.