Win a copy of Practice Tests for OCP Java 17 Certification Exam (1Z0-829) this week in the OCPJP forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Liutauras Vilda
Sheriffs:
  • Rob Spoor
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
  • Scott Selikoff
Bartenders:
  • Piet Souris
  • Jj Roberts
  • fred rosenberger

Understanding a DAO v Service seperation...

 
Ranch Hand
Posts: 194
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see designs/advice about layering an application as such:

Controllers|Commands<->Service|Manger Layer<->DAOs

(Of course all levels tend to deal with the domain objects)

However I tend to not see the benefit of the Service|Manger Layer, when using a more sophisticated ORM system backing the DAOs (such as JPA).

In almost all the examples I've seen, the service layer is merely proxying calls to the DAO not adding any new features. I can understand in the absence of a Mapping solution, when you need to manually assembly object graphs out of lower level calls to DAOs that it makes sense.

I also see some talk of transactional requirements, but I would still expect the data manipulations to be done directly via business calls on the domain objects and then merely persisted via the DAOs which are already configured to be single transaction...

What am I missing?
 
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Eric Nielsen:
In almost all the examples I've seen, the service layer is merely proxying calls to the DAO not adding any new features.



You are probably seeing the architecture applied where it isn't all that appropriate and where it doesn't add much value because most of the "business logic" are simply CRUD operations. Also the layered approach that you are quoting sounds more like the typical J2EE layering which has been shown to be not very object-oriented. Often the DAOs create "objects" that are little more than data transfer objects (i.e. very little behavior) which are then used in the service layer by SLSBs which are little more than transaction scripts.

If you are working with in a sufficiently complex domain then domain driven design (DDD) becomes worth while. DAOs are replaced with Repositories which are responsible for managing of the Entities, Value Objects and Aggregates - only functionality that doesn't seem to belong to any particular Entity is encapsulated in Services (no longer in a "layer" because much of the behavior now resides with the Entities). In this case the ORM is often abstracted through a "workspace interface" so that the Repositories can be unit tested with scripted workspace implementations instead of the full-blown (and slower) ORM (Applying Domain Driven Design and Patterns).

See also question on implementation in domain driven design, Domain Layer dependancy confusion and ORM Mapping, Best practices?

Does this address part of your concern?
[ March 27, 2008: Message edited by: Peer Reynders ]
 
Eric Nielsen
Ranch Hand
Posts: 194
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not really, but I might have explained my situation poorly...

When not using a ORM/JPA style solution, I've done some work where I had simple DAOs that, that were aggregated into a Repository style entity that handled building object graphs and a service layer that could handle the more transaction issues. Along with rather dumb DTOs and more intelligent domain objects.

In other projects where I'm able to use an ORM solution, I still commonly end up with a layer of DAOs (based on either Universal (ie type, id arguements and casting required) or Generic implementations (multiple copies of often near identical classes differing only in which type is used to instatiate the DAO). Here's there's often no need (that I've seen) for a repository layer... The DAOs are returning domain objects, not DTOs. And these domain objects are already complete object graphs. And I would expect most everything else would live on the domain objects themselves. I haven't studied DDD, but I suspect that's where my sympathies lie....

Here's a thread where I'm outlining one of my current places where I'm getting in trouble
https://coderanch.com/t/58204/Struts/Action-DAO-mess
While no one has responded there, I had posted a similar topic on the Struts mailing list and all of the replies were suggesting changing to an additional service layer between the Domain Objects and the DTOs.... It didn't sound "right" to me, but I didn't want to get into a design debate on that list on such an off-topic slant.... so I returned here.

(I will say I seem to have much better results getting responses in Testing & OO, Patterns, UML, and Refacotring, than in the other JavaRanch other forums when I post questions....)
[ March 26, 2008: Message edited by: Eric Nielsen ]
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Eric Nielsen:
In other projects where I'm able to use an ORM solution, I still commonly end up with a layer of DAOs (based on either Universal (ie type, id arguements and casting required) or Generic implementations (multiple copies of often near identical classes differing only in which type is used to instatiate the DAO). Here's there's often no need (that I've seen) for a repository layer...



I always felt that the introduction of an ORM actually made the DAOs superfluous - not the Repositories (which made the repeated appearance of DAOs in Hibernate's example code even more puzzling - I just assumed they hadn't wrapped their heads around Repositories yet). Typically DAOs are Table Data Gateways where one record in the table is equivalent to one object instance. Once the ORM takes care of things why do you need one-DAO-per-persisted-object (other than habit)? The concept of an Aggregate (cluster of associated objects treated as a unit for data changes (i.e. transaction)) however benefits from the support of a Repository, so one-Repository-per-persisted-Aggregate seems to make more sense, especially as most of the heavy lifting is already done by the ORM.


The DAOs are returning domain objects, not DTOs. And these domain objects are already complete object graphs.



The depletion of the service layer is natural as behavior that originally was assigned to transaction scripts in the service layer is now relocated to the appropriate Entities (objects).


And I would expect most everything else would live on the domain objects themselves.



Well, only almost everything - Services take care of the leftover bits.


I haven't studied DDD, but I suspect that's where my sympathies lie...



It ain't a silver bullet either. Overall it aims to be more maintainable in the long haul as it seeks to maximally align itself with the structure of the domain. But it is more suited to an environment where the object model can maintain its state in memory over a longer period of time. The request, objects-reconstitute, response, objects-disposal cycle common in web applications is less ideal as repeated restoration of the model's infrastructure could be expensive.


Here's a thread where I'm outlining one of my current places where I'm getting in trouble



Well, in my opinion the code in AddBug should actually be in a "Bug BugRepository.createBug(projectId, moduleId, submitter, assignee, versionIds)" method - and some people would interpret that as adding a service layer. And while such a method isn't necessarily placed on a DAO (presumably due to the dependencies on the lookup DAOs) there are no such restrictions for Repositories. Initially you would probably still have the Repository do the lookups manually in order to avoid duplication in logic - however if this became a performance issue it would be easy enough to simply add a support method in the workspace interface. The ORM could then implement the the support method directly to return the references necessary to create a "new Bug()" in one swoop - those references may already be in its identity map or they may have to be reconstituted from the database.
 
Eric Nielsen
Ranch Hand
Posts: 194
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So are you implying that with a JPA/Hibernate mapping solution the term DAO is typically inappropriate and the bottom layer in an application is/should be the Repositories (without really changing the default minimum interface exposed)? If so I think I would run into circular dependencies as each persisted entities often needs access to some of the other entities persistence handlers (whether they are called DAO or Repository). You noted the dependency problem in part of your reply, so I'm a little confused.

Yes adding a createBug/buildBug method "somewhere" would help in my code problem, but I still feel like that leads to a very anemic Repository since all its doing is building new items (all updates are taken care of already via the underlying DAO, all searches are already there) so the Repository adds one function and proxies/delegates everything else. Yes that one function requires access to multiple DAOs, so it needs to be at a higher layer...

So if you are using Hibernate(or other JPA provider) and you're suggesting DAOs are often only used out of habit.... can you show (or point to an on-line example, or suggest a physical book) that illustrates what the data-access layer should look like?
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Eric Nielsen:
So are you implying that with a JPA/Hibernate mapping solution the term DAO is typically inappropriate and the bottom layer in an application is/should be the Repositories (without really changing the default minimum interface exposed)? ... (whether they are called DAO or Repository).



Not exactly (Repositories are considered part of the domain model). DAOs are a heavily engrained pattern in the Java Community and their most common manifestation is what is known as a Table Data Gateway within the Pattern community. There is one Table Data Gateway for each table in the database an each record contains the data that represents one object instance. So the set of Table Data Gateways is a direct reflection of the underlying data model - so this part of your application is tightly coupled to your database schema.

Using an ORM breaks that tight-coupling because once properly configured it manages object reconstitution, update and relationships for you - so why stick with the limiting one DAO per (table) class hierarchy model?

Repositories that deal only with a single class hierarchy look like DAOs - but whenever possible they should be dealing with Aggregates (Whole part object cluster that is usually instantiated (not considering lazy load) and persisted (in the same transaction) all at once while other domain objects are only allowed to reference the aggregate root and use the the aggregate root identity but not those of the parts).


If so I think I would run into circular dependencies as each persisted entities often needs access to some of the other entities persistence handlers



But the ORM actually handles persistence, not the Repositories/DOAs. So if you already have the object's "identity" there is no need to go to the Repository - you can go directly to the workspace because you are going to get exactly the same object. The cost of this solution is that your Repositories have to work against a workspace interface that abstracts the ORM API so that you can slip in a mock implementation for unit testing.


but I still feel like that leads to a very anemic Repository since all its doing is building new items (all updates are taken care of already via the underlying DAO, all searches are already there)



The idea is to move the most of the functionality that is in the DAOs into the Repositories, while the generic parts are moved into the workspace implementation.


can you show (or point to an on-line example, or suggest a physical book) that illustrates what the data-access layer should look like?



The discussion draws heavily on Applying Domain Driven Design and Patterns which unfortunately is based on .NET and NHibernate but the principles should still be valid.

See also JAOO: NWorkspace, NWorkspace Why? and NWorkspace.
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
... for now you should probably simply stick with AddBug as you have it now and accept that it is a kind of "service". Elaborate changes are really only warranted if this sort of thing is going occur repeatedly.
 
Eric Nielsen
Ranch Hand
Posts: 194
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. I've ordered that book (and the other DDD one too). I'm seeing a glimmering of how this could work.

In the short term I'm going to try leveraging some of Struts2 features that I think will let me avoid the need for introducing the service via type conversion on the incoming requests (ie rehydrating from keys to domain objects before the app see them). Longer term will wait until I cab absorb the information in the books. My domain isn't actually bug tracking, it was a useful analog, albeit a much simpler one.
 
Peer Reynders
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Eric Nielsen:
Thanks. I've ordered that book (and the other DDD one too).



Hopefully you already own Patterns of Enterprise Application Architecture because those two books reference it heavily.
 
Eric Nielsen
Ranch Hand
Posts: 194
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yeah that tome has been on my bookshelf (and read several times) for a while. It came in very handy when I was writing my own ORM solution...
 
reply
    Bookmark Topic Watch Topic
  • New Topic