0

How can I make a DAO object a property of other DAO?

Say I have an Employee object with a Department property

public class Employee {
     public Department;

      //setter and getters
  }

I had this EmployeeDAO and DepartmentDAO interfaces with corresponding implementations

And I had DAOFactory

public abstract class DAOFactory {

// db connection instantiation here

public IEmployeeDAO getEmployeeDAO() {
    return new EmployeeDAOImpl(this);
}

public IDepartmentDAO getDepartmentDAO() {
    return new DepartmentDAOImpl(this);
}

}

i had a servlet where instantiate this DAOfactory

public class EmployeeController extends HttpServlet {

public EmployeeController() {
    super();
    DBUtils dbInstance = DBUtils.getInstance("mysql");
    System.out.println("DAOFactory successfully obtained: " + dbInstance);

    // Obtain UserDAO.
    employeeDAO = dbInstance.getEmployeeDAO();
    departmentDAO = dbInstance.getDepartmentDAO();
    jobDAO = dbInstance.getJobDAO();

}
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

            employees = employeeDAO.findAll();

            request.setAttribute("employees", employees);

}

my question is how can I map the Department object inside the employeeDAO or its implementation when I call the findAll method of the employeeDAO?

I had something like this in my attempt to map the results :

    private  Employee map(ResultSet rs) throws SQLException {
    Employee employee = new Employee();

    employee.setEmployeeID(rs.getInt("EMPLOYEE_ID"));
    employee.setFirstName(rs.getString("FIRST_NAME"));
    employee.setLastName(rs.getString("LAST_NAME"));

    Department department = new DepartmentDAOImpl().getDepartmentByID(rs
            .getInt("DEPARTMENT_ID"));

    employee.setDepartment(department);

    return employee;
}

But I think this is a wrong approach. Can someone help me with this?

Gm Chill
  • 3
  • 2
  • Why should this be the wrong approach? Is anything not working as expected? (Although I would consider using JPA instead of manual object mapping because it does all the dao for you. And while at it find a higher level abstraction than extending HttpServlets) – zapl Jun 05 '16 at 13:37
  • Because I am directly creating an instance of the DAO implementation which is supposed to be hidden/or shadowed by the DAO interface. What I was aiming is to make this possible once I call the employeeDAO.findAll(); I have seen some articles about JPA too. I plan on implementing it to in my future projects. – Gm Chill Jun 05 '16 at 13:46

1 Answers1

0

You EmployeeDAOImpl has a dependency on a IDepartmentDAO. Instead of directrly instantiating one, declare it as dependency and let the code that constructs the EmployeeDAOImpl figure out how to resolve it.

Assuming

interface IEmployeeDAO {
    Employee load(long id);
}
interface IDepartmentDAO  {
    Department load(long id);
}

as the interfaces require the needed dao in the constructor

class EmployeeDAOImpl implements IEmployeeDAO {

    private final DAOFactory factory;
    private final IDepartmentDAO departmentDAO;

    public EmployeeDAOImpl(DAOFactory factory, IDepartmentDAO departmentDAO) {
        this.factory = factory;
        this.departmentDAO = departmentDAO;
    }
    ...

and now you can use it anywhere. e.g.

@Override
public Employee load(long id) {
    ...
    long departmentId = ....
    Department department = departmentDAO.load(departmentId);
    employee.department = department;
    return employee;
}

Your DAOFactory which knows which kind of implementations you use anyways can now provide the dependencies by adding a simple parameter

public IEmployeeDAO getEmployeeDAO() {
    return new EmployeeDAOImpl(this, getDepartmentDAO());
}
zapl
  • 63,179
  • 10
  • 123
  • 154
  • Thank you very much for helping me out sir. – Gm Chill Jun 06 '16 at 08:56
  • Oh, another question, how can I instantiate the Department DAO if I had a manager object which extends the employee class as its property? – Gm Chill Jun 06 '16 at 08:58
  • @GmChill Same way maybe (make it an argument of the constructor). But I'm also not sure how you mean that. A manger should usually not `extend` the thing it manages, it merely needs a reference to the thing: ["What is the Liskov Substitution Principle?"](http://stackoverflow.com/questions/56860/what-is-the-liskov-substitution-principle) – zapl Jun 06 '16 at 09:22
  • I'm still confused but I think I am getting what I am doing wrong. Thank you very much sir zapl for helping. – Gm Chill Jun 09 '16 at 02:15