Help

So, I've been following this discussion with interest. I'm still confused. All I'm really getting out of the comments on this thread is: there's some other objects in the system that aren't DAOs or entities. But I knew that already. Clearly, I need to actually read the damn book for myself. Still, it really doesn't fill me with confidence that people who /have/ read the book don't seem to be able to explain (in words or code) the Repository notion coherently. And it looks like everyone has their own private take on what exactly a Repository is all about. This gives me a hint that the idea is not especially well-defined.

What I still need to hear from proponents of this idea is a clear accounting of:

  • what problem does it solve?
  • how do I tell when I need to use it?
  • how do I tell which functionality belongs in the Repository, which on the Entity, and which on the DAO?
  • what are the costs of using it?

And I want these folks to take seriously the following question:

Do we /really/ need another stupid layer in our already horribly over-engineered Java applications?

Enough layers already, goddammit! :-)

UPDATE: Fabio Kung has written a nice explanation of his understanding of the semantics of a repository, and there's nothing there that I really object to. Except that, what he's describing is pretty much what my understanding of the DAO pattern has /always/ been. I have never understood that a DAO was persistence specific from the point of view of the client. It's just a source of objects. Where it gets those object from is its own business. I sorta thought that was the whole point...

27 comments:
 
12. Nov 2007, 21:59 CET | Link

Hi Gavin,

Sorry, I was replying it here, but wasn't sure if my code would be formatted (and the reply started to become really big).

So, I commented here.

ReplyQuote
 
12. Nov 2007, 21:53 CET | Link
Alexandre Poitras

From what I understand, DAOs and Repositories are quite different conceptually and have very different purpose. Repositories are expressed in term of business objects and thus have to obey certain rules (one repository per aggregate for instance). On the other hand, DAOs only address th e problem of encapsulating the data mapper layer. There is no rule about their granularity and how they fit in the domain model.

Technically, they are the same objects. You don't need a layer of Repositories and of DAOs. They are the same thing especially if you are using an ORM framework. See http://martinfowler.com/eaaCatalog/repository.html Look like a DAO to me.

By the way, I think the real question Christian was bringing was : Is it okay to reference a DAO from an domain (entity) object. I think it's alright in a lot of cases but I know lot of people who disagree.

 
12. Nov 2007, 23:00 CET | Link

Maybe i'm just not seeing the issue here, but isn't Repositories not just an example of the way we normally recommend using a Strategy to decouple the domain objects from the persistence layers in both the HiA book and training material...

 
13. Nov 2007, 01:09 CET | Link
Ian Cooper

Hi Gavin,

Try this. While I am sure you won't agree with all of it I do discuss repositories with relation to LINQ:

http://iancooper.spaces.live.com/blog/cns%21844BD2811F9ABE9C%21397.entry

The key is:

They act like a collection, but we don't care where

Internally they are expressed in terms of the domain, so we don't query within in terms of SQL but in the language of the domain. SO HQL etc are fine, but SQL is not. We can talk to an ORM for persistence, but not create SQL update statements etc.

By contrast a DAO might contain SQL statements i.e. the relational schema may bleed into them. In .NET terms I might use raw ADO.NET like SQLConnnection or SQLCommand inside them.

Because a repository is clean of schema info it can live in the domain without polluting it, and talk to infrastructure services, such as an ORM, which live outside the domain.

A DAO risks polluting the domain with embedded schema knowledge, so we keep it at arms length.

 
13. Nov 2007, 01:52 CET | Link

IMHO the transparent persistence, allows us to use Entities as DTOs. Definition of extra DTOs to map entity beans is an anti-DRY pattern, really an anti-pattern.

 
13. Nov 2007, 02:48 CET | Link

Ian, if you click the green question mark in the comment editor, you'll get an explanation of the wiki text syntax. To make a link, use the following:

[some optional text=>http://the.link]
 
13. Nov 2007, 02:49 CET | Link
Technically, they are the same objects. You don't need a layer of Repositories and of DAOs. They are the same thing especially if you are using an ORM framework. See http://martinfowler.com/eaaCatalog/repository.html Look like a DAO to me.

Yeah, looks /exactly/ like a DAO to me.

 
13. Nov 2007, 08:27 CET | Link
Xavier

When you take a look at the dao pattern , it seems to use TransferObjects as input/output whereas repository uses entities (which are more than TO to me). It seems that the (core) dao pattern does not provide an in-memory illusion of the storage mechanism: ask 2 times the same object to a dao and you'll get 2 different copies; modify a TO provided by a dao, until you call an explicit save/update, nothing will be written in database. That's how I tell the difference between a dao and a repository (so my repository is your dao ;-)). That's my interpretation and not everyone needs to agree with me.

 
13. Nov 2007, 08:47 CET | Link
Magnus Heino
That's my interpretation and not everyone needs to agree with me.

I agree completely. And maybe this is how Gavin and Christian is using it too, but it sure isn't in the dao pattern... and thats what patterns are all about, communication...

Also, with recent years popular use or generic daos, and now many people seems to use entitymanager as a replacement for those daos, the aggregate root pattern is very usable thing to think about, and that comes hand in hand with the purpose of the repository. It is not likely that you want to expose all mapped entities with generic daos or with an injected entitymanager. You could either choose to have a rule that everyone should apply that says what is allowed and what is not, or you could enforce it with the repository pattern.

 
13. Nov 2007, 09:28 CET | Link
Heiko Rupp

Gavin,

Do we really need another stupid layer in our already horribly over-engineered Java applications?

it looks like the salary of IT architects is directly tied to the number of patterns/layers they can introduce into Hello World. This repository thingy makes perfect sense in that context.

 
13. Nov 2007, 10:05 CET | Link

Hi Gavin,

Thanks for help with the wiki. I was trying to post a link to a blog I wrote around LINQ, which covers some of these concepts, in passing.

The key point, expressed here by a few posters, is that the repository is implemented in terms of the domain. Specifically the relational schema (or whatever storage medium you have) must not bleed into the repository i.e. no SQL statements. If you are using an ORM you tend to be fine on this score as you use the services of the ORM for CRUD, with queries expressed in a DSL like LINQ or HQL. That is why a repository is said to be part of the domain, because it only uses what the domain knows about. Conversely a DAO protects your domain from the relational schema by encapsulating your dynamic SQL and stored procedure calls. But because it contains a dependency on the relational schema it needs to be in a separate layer.

Once you have an ORM and DSL for querying, the reason for a repository is to prevent duplication and centralize your interaction, not to insulate you from relational schema. You could use any domain level service call your ORM, but that would result in duplicated query logic and shotgun surgery when you wanted to change anything, so the repository just encapsulates your interaction with the ORM.

The kicker is that the terms are misused. A lot of folks provide their implementation in an ORM and call it a DAO, and a lot of folks provide their implementation in SQL and call it a repository. I'll admit to making this mistake early on when understanding repositories.

With a repository of course, ideas like keeping the session outside so that the caller decides when to persist, become much more agreeable, because folks stop worrying that they are somehow bleeding details from the DAL over into the domain. Indeed, once you have an ORM, you may no longer need a DAL, because the ORM tool is your DAL for any operations that you defer to it.

Of course there are always places where you end-run around the ORM and those need to still live in a DAL, but the point is the same.

Make more sense?

 
13. Nov 2007, 10:03 CET | Link
Xavier

Repositories do not introduce a new layer as it is part of your domain model layer. Think about the place of a dao/repository layer:

  • should it be on top of your entity model layer (which may contain logic)? Then you'd end up with a data access layer above your business logic (seems strange to me).
  • should it then be beneath your entity model? Then your dao/repository interfaces will have a direct dependency on the above layer (not a good idea to me).

So, if it cannot be above or beneath your domain layer, it must be part of it. Once again, this is my own conclusion and everybody is free to think different.

 
13. Nov 2007, 10:18 CET | Link

Well, fair enough - it sounds like you guys are working from a much narrower definition of DAO than we are. It sounds like our DAO is basically the same thing that you guys call a Repository.

(I don't think our usage is uncommon, by the way.)

 
13. Nov 2007, 10:29 CET | Link

Yes, I think I found the origin of it: DAOs are 1:1 to SQL tables in one of the blog entries. I've never seen that restriction anywhere, but if it helps to invent new terms and constructs that solve this nonexistent problem... pay raise for the architects :)

 
13. Nov 2007, 13:54 CET | Link
Sakuraba

Are we actually discussing the need for another layer in java webapps that we cannot define in what it does or what it is good for? Why not just give up on that damn thing? We have enough complexity, we dont need new ones, where we dont even know what it is good for..... Didnt we learn anything from the Rails guys? ;)

Regarding the textarea I am writing into right now, it does not react on tab navigation in Safari 3 on Leopard. All the other text fields can get tabbed through, but when tab from the subject field, I land at the math-question-verification field.

Is this behaviour wanted or should I create an Issue in a JIRA somewhere? ;) ;)

 
13. Nov 2007, 13:50 CET | Link
Francisco Antônio
Enough layers already, goddammit! :-)

A long time ago we had spaghetti code...now we have lasagna code. Layer over layer over layer...

I want to be a programmer but I don't like lines of code: the less of them the better :)

Cheers Francisco Antônio

 
13. Nov 2007, 13:42 CET | Link
Gerson K. Motoyama | gersonk(AT)gmail.com
It sounds like our DAO is basically the same thing that you guys call a Repository.

Hi Gavin, Your DAOs would really be the same thing (have same meaning) as the Repositories (DDD) if they care about domain concepts, in DDD terms (see Ubiquitous language). Repository is part of domain and you use it for providing access to the aggregate roots. The implementation of your DAOs maybe similar to a Repository, but the key of DDD is not that.

 
13. Nov 2007, 18:35 CET | Link
Gilles Philippart

I read Fabio's post and i find that the client.findOrders(sinceDate) will completely grieve your performance when you're trying to do bulk processing. What if you want to retrieve all orders from 100 clients since some date at a time for reporting purpose ? You'll have to create a Clients class ? Looks like weird from my point of view... I'm working on a project where some DDD principles had been applied, and are progressively removing everything, keeping only 3 layers (service, model, dao). Much more reusable. Being pragmatic sometimes helps too. Keep it simple.

 
13. Nov 2007, 18:45 CET | Link
Xavier
Yes, I think I found the origin of it: DAOs are 1:1 to SQL tables in one of the blog entries. I've never seen that restriction anywhere, but if it helps to invent new terms and constructs that solve this nonexistent problem... pay raise for the architects :)

I think you're absolutely right: nothing dictates a 1:1 relationship between tables and DAOs but some tools have popularized this false idea (like this one: http://www.hibernate.org/328.809.html). In the end, many people think it is a de facto best practice to have a dao for each entity. To get rid of that bad habit, one had to dump the name dao as well and come up with a new one (repository)... but it would have been better to explain why this was bad in the first place.

 
14. Nov 2007, 09:03 CET | Link

Gavin,

Reading the article by Alistair Cockburn about hexagonal architecture helped me a lot understand the DDD architecture approach, especially for repositories and GUI.

http://alistair.cockburn.us/index.php/Hexagonal_architecture

 
14. Nov 2007, 21:39 CET | Link
Samer Kanjo | samer(AT)kanjo.net

Gavin, I have been following this thread as it seemed to spawn from your silliest post ever article. I recently read the DDD book and also wondered about the differences between Repository and DAO. They seemed to be the same to me. The book never actually discusses DAO.

I started to write a post to get some answers to my questions from the DDD group over at Yahoo. In the course of writing the post I end up answering my own questions. I have concluded that the two are essentially the same with some slight differences. However, those differences really depend on your own definition of DAO.

You can find the article here:

http://tech.groups.yahoo.com/group/domaindrivendesign/message/6258

 
14. Nov 2007, 21:54 CET | Link
Samer Kanjo | samer(AT)kanjo.net

That link I pasted didn't seem to be syntaxically correct as I included the protocol in th URL. Here it is again:

tech.groups.yahoo.com/group/domaindrivendesign/message/6258

 
14. Nov 2007, 23:45 CET | Link
Samer Kanjo | samer(AT)kanjo.net

The link in my last post did not work yet again so I tried some things including clicking the ? on the left. Only that got me a 404. I then Googled for Hibernate Wiki Text Markup and found what used to be the page on your site. Clicking the link took me to a blank page. The Google cache actually had the Wiki Text Markup help so now I know how to post a link:

http://tech.group.yahoo.com/group/domaindrivendesign/message/6258

Perhaps you guys could have a look at the help page and the help link in the comments section.

 
19. Nov 2007, 13:51 CET | Link
I read Fabio's post and i find that the client.findOrders(sinceDate) will completely grieve your performance when you're trying to do bulk processing. What if you want to retrieve all orders from 100 clients since some date at a time for reporting purpose ? You'll have to create a Clients class ? Looks like weird from my point of view... I'm working on a project where some DDD principles had been applied, and are progressively removing everything, keeping only 3 layers (service, model, dao). Much more reusable. Being pragmatic sometimes helps too. Keep it simple.

Hi Gilles,

You haven't got the point. My example was given a client, I want his orders since.... I wanted the Orders for one client. If I wanted all orders for 100 clients (your case), I wouldn't implement it that way. Maybe a method in the ClientsRepository (or OrdersRepository) would be sufficient.

That isn't an excuse not to be using DDD. Sorry, but you should first understand it.

19. Nov 2007, 14:07 CET | Link

@Samer Writing this comment, I see the ? icon right before the Comment field. Is that what you want?

 
23. Nov 2007, 20:44 CET | Link
Chuck Canning

The URL to the yahoo groups is incorrect. It is

http://tech.groups.yahoo.com/group/domaindrivendesign/message/6258

Also, this blog and comments were very helpful because I was trying to fiugre out how the Repository was different then the DAO based on various implementations (like Spring uses both).

 
31. May 2008, 08:36 CET | Link
bogdan

Is this a valid conclusion? Today's DAO are much liky a Repository and today's DAO are NOT a Table Data Gateway (not a DAO for every table but a DAO for a root only, the rest is done by Hibernate's fetching)

Post Comment