1

I have these two classes (Getter/Setter/Constructor omitted):

public class Company {
    private String name;
    private String adress;
    private List<Employee> employees;
    private Uuid id;
}

public class Employee {
    private String name;
    private int age;
    private Uuid id;
}

The two entities and their relationship are modeled in a relational database using the tables COMPANY, EMPLOYEE and EMPLOYMENT.

Now I want to write the DAO classes to manage persistance of the two entities and their relationship. The easy way would be making a DAO for each one and have the CompanyDao use the EmployeeDao internally. But according to some Stackoverflow answers I've read, this is a design smell and should be refactored into service methods which use the DAOs without them having to depend on each other.

This is the way I would implement this service method:

public class DBService {
    public DBService(CompanyDao companyDao, EmployeeDao employeeDao,
                     EmploymentDao employmentDao) { ... }

    public Company findCompany(Uuid companyId) {
        Company company = companyDao.find(companyId);
        List<Uuid> employeeIds = employmentDao.findEmployeeIds(company.getId());
        for(Uuid employeeId : employeeIds) {
            company.addEmployee(employeeDao.find(employeeId));
        }
    }
}

Is this a good way to do this? Or should the EmployeeDao have a findByCompany(Uuid companyId) method?

Info: I already asked a smiliar question on Stackoverflow, but the only answers I got was "Use an ORM tool". I know that something like Hibernate would manage all of the persistance for me, but I would like to know how to do this by hand.

  • Do you need to handle Employee-objects independently, without a Company object? – COME FROM Jun 20 '16 at 11:35
  • @COMEFROM This was only an example, but yes, the Employees might be used on their own. – Luca Fülbier Jun 20 '16 at 16:42
  • Ok. I don't think this question can be answered without knowing the reasons behind the design decision of having direct object references Company->Employee. If Employee is an independent entity (and not only a part of a Company as an aggregate), then the decision is not obvious. Using an ORM does not solve this design issue either. It only helps with the implementation. – COME FROM Jun 21 '16 at 12:00
  • What is the problem with Employee being a separate Entity? Like i said in my answer, i also have Company and Employee as separate entities in my database and a relationship table that links them. Doesn't this directly translate to Employee being a field of Company? – Luca Fülbier Jun 21 '16 at 14:03
  • No, relationships of entities don't directly translate to object references. It's always a design choice. Choosing direct object references by default lead to large aggregates which will hurt scalability and performance. It's hard to keep all data consistent while juggling large snapshots of data in memory for many sessions and users. – COME FROM Jun 21 '16 at 15:00
1

The easy way would be making a DAO for each one and have the CompanyDao use the EmployeeDao internally.

Due to no link to StackOverflow has been shared, I just want to mention why is code smell.

In short:

  • it would introduce undesirable coupling. Potentially one of the DAOs would end up subordinated to the other.

  • It has all the recipes for a circular dependency. See also Circular references.

Regarding to the code (the exmaple of DBService)

Is this a good way to do this?

So far, the code is at the doors of the well known Repository pattern (despite the actual name) which is broadly adopted by the community. You will find many references to the pattern looking for DDD.

The Repository pattern introduced in Eric Evans' DDD, has nothing to do with the implementation details, so the implementation will vary according to the specific requirements and needs.

What doesn't vary is the concept. The purpose.

So, based only in the info you provide, I would say that you are doing fairly good.

  • It has been quite a while since i asked this. I solved it pretty much the way you described, adding a DAO for every entity (encapsulating the low-level data access for different databases, like MySQL and SQLite) and adding a higher-level repository, which coordinates the cross-DAO coordination of actions that require changes in different places. Works like a charm. I would however recommend using some kind of dependency injection or a builder pattern to reduce the overall dependency clutter for the repositories (the constructor in the original post is quite long already). – Luca Fülbier May 25 '17 at 6:07
  • At least you have experienced the drawbacks of manually DI. Plus it (I guess) exposed a weakness in your design (oversized dependencies) and that's good. – Laiv May 25 '17 at 6:28
0

I suggest a high symmetry. So if you have an entity you should have a DAO. The DAO should serve only one entity. (principle of least surprise)

You also should keep dependencies short so a DAO is only responsible for its entity and the resolution of direct neighbours. (Law of demeter)

In an architecture of mine I use other DAOs within DAOSs. But the behavior I use from other DAOs is nothing about "loading" or "persisting". I only use map-methods to create a new representation for each entity for the higher layer.

By the way: This has nothing to do with hibernate an ORM tools. They only decrease mapping effort and support loading, persisting and caching strategies. But all of this should be encapsulated in the DAO layer either so higher layers can abstract from those technical details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.