3

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.

8
  • Do you need to handle Employee-objects independently, without a Company object? Commented Jun 20, 2016 at 11:35
  • @COMEFROM This was only an example, but yes, the Employees might be used on their own. Commented Jun 20, 2016 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. Commented Jun 21, 2016 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? Commented Jun 21, 2016 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. Commented Jun 21, 2016 at 15:00

2 Answers 2

2

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.

2
  • 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). Commented May 25, 2017 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. Commented May 25, 2017 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.