Announcement Announcement Module
No announcement yet.
DAO/update vs Unit of Work Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • DAO/update vs Unit of Work

    Hi All, I wanted to discuss this issue.

    I have a relatively complex domain model object graph with a lot of cross-references b/w objects. I've been always using DAO objects for my data access needs and continue to use them. However, the thing that often puzzles me is that unit of work concept (available via Hibernate and other ORM) essentially makes modification operations within DAO obsolete.

    For instance, a hypothetic relatives domain and RelativesDao example:

    public class Person {
      String id;
      String name;
      List<Relative> relatives;
    public class Relative {
      Relationship relationship; // enum: father, brother, mother, sister, husband, etc
      Person person;
    public interface RelativesDao {
      public Person getPersonById(String id);
      public List<Person> findPersonsByName(String name);
      public void createPerson(Person person);
      public void deletePerson(Person person);
      public void savePerson(Person person);
    Given that person/relationship graph could be very deep and branchy it seems that DAO.savePerson(...) is not just useless, but also misleading. ORM tools can easily track any changes to any objects within the graph, provided these changes are done within the same session. If the detached objects are involved, the merge operations taking place in savePerson() and such are often unnecessary complex and bug-prone.

    I was wondering if anyone has given this a thought and possibly has best practices recommendation for such cases.

  • #2
    This is one of the topics that Spring guys and JBoss guys have opposite views and like to argue about.
    The Spring way is to layer everything - always create the interfaces with the methods that will contain the application functionality and make sure that the implementation can work regardless of the environment (in this case - the DAOs will work in a non-web or any other GUI environment - they should provide the exact same functionality in a unit test or a main method).
    The benefits of this approach are that your can unit test your DAOs and you will know exactly what functionality is provided by the persistence layer (if you unit tested your DAO appropriately, there should not be any user input that will cause an unexpected behavior by your DAO).

    The opposite approach, which can be seen a lot in Seam examples, is not layering - let the users do whatever they want with the objects and then flush them to the database. You can see in such examples that the flush is done in the presentation layer. What I think is extremely dangerous with this approach is that the user may sometimes make changes to persistent objects but not all of them should really be persisted, so as a developer you have to be extra-careful to prevent such cases, as the flushing will cause the persisting of ALL changes.

    In my opinion, the layered approach is better for the reasons I described above. Do note that having save/update/delete methods for a domain class doesn't mean you have to implement the entire saving/updating/deleting mechanism - usually you can use the ORM tool's mappings to do it (cascade for example). For complex persistence operations (for example saving several unrelated domain objects) I recommend writing a service class, which will delegate to one or more DAOs. Service classes are also the appropriate place to do transaction management.