What is the difference between DAO and Repository patterns?
Asked Answered
S

14

569

What is the difference between Data Access Objects (DAO) and Repository patterns? I am developing an application using Enterprise Java Beans (EJB3), Hibernate ORM as infrastructure, and Domain-Driven Design (DDD) and Test-Driven Development (TDD) as design techniques.

Seanseana answered 18/12, 2011 at 6:5 Comment(2)
A Repository IS a Dao, since it allows you to access/persist data, but the repository has a more precise definition based on simulating interaction with a collection of data. This definition and the expected benefits can be found in DDD by Eric Evans.Derogative
Two types of explanations can be found in below answers: 1. They differ in the level of abstraction with data access; 2. No difference at all since they are doing the same job, ie. hide the implementation details of the accessing dataGan
M
652

DAO is an abstraction of data persistence.
Repository is an abstraction of a collection of objects.

DAO would be considered closer to the database, often table-centric.
Repository would be considered closer to the Domain, dealing only in Aggregate Roots.

Repository could be implemented using DAO's, but you wouldn't do the opposite.

Also, a Repository is generally a narrower interface. It should be simply a collection of objects, with a Get(id), Find(ISpecification), Add(Entity).

A method like Update is appropriate on a DAO, but not a Repository - when using a Repository, changes to entities would usually be tracked by separate UnitOfWork.

It does seem common to see implementations called a Repository that is really more of a DAO, and hence I think there is some confusion about the difference between them.

Massenet answered 18/12, 2011 at 6:29 Comment(22)
Ok, but usually the code for abstract DAO and repository looks very similar; am I right?Seanseana
@Thurein: It seems common to see a Repository that is really more of a DAO abstraction mis-named. A Repository that stays true to the pattern would have a single Get(id) method and perhaps a Find(ISpecification) method. Changes to Entities would be automatically tracked by a UnitOfWork, and the Repository would register the Entities with the UoW as they are loaded. So, no, a Repository should be different from a DAO.Massenet
Thanks for the explanation, I have a doubt, is it possible to have a repository interface in the domain layer and implement that repository interface using dao in the infrastructure layer.Seanseana
Well, you wouldn't want your DAO class to literally implement your IRepository interface. You would want your repository to use DAO's in its implementation. Remember, a DAO will be a per-table object, whereas a Repository will almost always have to use multiple DAO's to build a single Entity. If you find that is not the case, that your Repository and Entity only need to access a single table, then you are most likely building an anemic domain.Massenet
I though, DAOs are not per-table object. That might be the fact that confused me.Seanseana
In my experience, there is a DAO for each table (and maybe more). Often the DAO can be generic and uses reflection or auto-generated code based off the database tables directly.Massenet
I've noticed in the .NET world specifically the term "Repository" is used to refer to what is essentially a DAO; "DAO" is more of a Java term.Bahaism
Design patterns are as harmful as they are helpful.Rag
not really and the way Repository is used in latest frameworks (e.g. see Spring, or spring-data), confirms that Repository is actually the 'dumber' one of the two. Repository (same as DAO) is an abstraction to hide where and how data is retrieved/saved (note save/update IS part of a repository's responsibilities). DAO is basically the same, though you can see it as a slightly broader concept. If you want to use both, a DAO could use a Repository or a set of repositories to access your data from. Note that some call DAO-s providers. (e.g. UserInformationProvider rather than UserInformationDao).Plural
@Seanseana DAO-s are not per table, the pattern is only abstracting the access to your data - you can implement that however you like (per table, or per group or models). The recommended way is to always shape your DAOs based on your domain model rather than taking underlying persistence into account tough as that makes it easier/clearer to use and gives you a bit more flexibility on how you persist it (e.g. imagine you'll need a DAO that stores your data in XML files or gets it from a message queue rather than from Database ...).Plural
@Plural I disagree. A DAO returns data by its very definition (a data access object). A repository, by its definition, returns domain objects. It should stand to reason that the repository would use DAOs and not the other way around, because in OOP we compose domain objects out of one or more data objects, and not the other way around.Statocyst
@MihaiDanila, sorry I just saw your comment. Yes, DAO is an object that allow you to access data, and same as Repository, it abstracts the database connection and communication and returns domain objects instead of ResultSet or other DB specifics. Conceptually, you could even consider them identical. But if you look at how they are used, you'll notice that either it's only one used, or DAO connects to the Repository. The way they are used is as I described in an answer below. Repository handles one type of objects (usually from one table), while DAO is more loose and can handle related models.Plural
You mention Add(Entity) as an example on Repository pattern. However the Repository is to abstract all persistance, hence it's inside the domain and works only with domain/business objects, not with Entities. A repository should not expose table representations (Entities)Surat
Why is a Repository a "Read Only" concept while DAO is "Read and Write"?Nacreous
Same question as Dennis has. Why shouldn't we have delete/update method inside Repository? Tons of other guides keep showing the opposite. Why is there so much ambiguity?Electrodynamics
Debasish Ghosh says that the main difference is that DAOs deal with just one table (flat model), while Repositories deal with aggreates (like Hibernate does for us).Gibbie
While it's true that DAOs and Repositories tend to be used interchangeably and tend to share some aspects with the other in reality, Repository pattern is necessary when you are dealing with: 1. Same domain model having to support two different databases (because of client preference, costs or vendor advantages) 2. Long-running projects where you think you may have to switch databases as you discover your domain 3. Greenfield projects, where you have no clue what kind of database is the right fit but want to start developing and getting the application to end-usersVilayet
Can i say, the repository pattern is for accessing more than one data store? If i have one data store and just want to convert a business object to an entity, can use the Adapter Pattern; right?Arnoldarnoldo
If you are trying to fit DAOs and repositories into a single data layer, it is a good possibility that you are over-abstracting. In fact, in some cases I will fit each DAO / DTO pair into a single per-entity class and divide by entity instead of by aspect (for example, UserDataObject and AccountDataObject). Where possible. I try not to mix OOP with AOP ("where possible" being key). Obviously, the data layer itself is AOP concept, but inside that, I try to keep it OO if I can. One of the main pillars of OO is that each class takes care of itself (encapsulates all of its properties and logic.)Newscast
Eric Evans (Domain-Driven Design) describes that repositories should emulate a collection of objects but Vaughn Vernon (Implementing Domain-Driven Design) makes a distinction between collection-based repositories and persistence-based repositories. So if your repositories work with objects that are direct representations of your database and you're not using repositories as in-memory collections (just using it to abstract the database), you're pretty much doing the same as a traditional DAO would do.Raveaux
@Raveaux made a very good point here, as for example in case of Spring Data the Repository acts as a DAO, it is a "persistence-based" repository.Canzona
@Massenet Thank you so much for explaining this. I'm trying to learn how to build databases for mobile devices in Android Studio, and the tutorials don't do a thorough job of explaining what the DAO is versus a Repository. (I've learned to start researching vocabulary when they use it.)Ringsmuth
P
154

OK, think I can explain better what I've put in comments :). So, basically, you can see both those as the same, though DAO is a more flexible pattern than Repository. If you want to use both, you would use the Repository in your DAO-s. I'll explain each of them below:

REPOSITORY:

It's a repository of a specific type of objects - it allows you to search for a specific type of objects as well as store them. Usually it will ONLY handle one type of objects. E.g. AppleRepository would allow you to do AppleRepository.findAll(criteria) or AppleRepository.save(juicyApple). Note that the Repository is using Domain Model terms (not DB terms - nothing related to how data is persisted anywhere).

A repository will most likely store all data in the same table, whereas the pattern doesn't require that. The fact that it only handles one type of data though, makes it logically connected to one main table (if used for DB persistence).

DAO - data access object (in other words - object used to access data)

A DAO is a class that locates data for you (it is mostly a finder, but it's commonly used to also store the data). The pattern doesn't restrict you to store data of the same type, thus you can easily have a DAO that locates/stores related objects.

E.g. you can easily have UserDao that exposes methods like

Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)

All those are related to User (and security) and can be specified under then same DAO. This is not the case for Repository.

Finally

Note that both patterns really mean the same (they store data and they abstract the access to it and they are both expressed closer to the domain model and hardly contain any DB reference), but the way they are used can be slightly different, DAO being a bit more flexible/generic, while Repository is a bit more specific and restrictive to a type only.

Plural answered 20/3, 2013 at 0:48 Comment(8)
If I get this right e.g. I have something like CarDescription that has e.g. language_id as foreign key - then to retrieve that I should do something like this: CarRepository.getAll(new Criteria(carOwner.id, language.id)); which would give me all cars of a language in a specific language - is that the right way to do it?Sorrow
@StefanFalk, have a look at Spring Data, it allows you to do much nicer calls than that. e.g. that could be written like CarRepository.findByLanguageId(language.id) and you wouldn't even need to write the code, you just define the interface with a method with that name and Spring Data takes care of building the default class implementation for you. Pretty neat stuff ;)Plural
This shows how to write queries in Spring Data but would I need that if I'm using Hibernate? Or would I just implement TodoReporitory in another class that then implements those methods like MyRepository extends TodoRepository where MyRepository uses Hibernate for the persistence stuff. There is just sooo much information out there and I'm starting to get confused in the middle of a project where I already have a larger database and already a server/client communicationSorrow
The beauty of Spring Data is that you don't actually have to write the queries, you just create an interface (like that TodoRepository in your example, which has the method findById). And you are practically done. What then Spring Data does is, it finds all these interfaces you've created which extend the Repository interface and creates the classes for you. You'll never see those classes and you won't be able to create new instances, but you don't need to as you can just autowire the interface and let Spring locate that repository object.Plural
Finally, you don't have to use Spring Data, you can go the old way of writing the query methods yourself (using Criteria API etc), but you'd just make your life a bit more complex ... You might say that you would have more flexibility like that, but that's not true either as if you really want to go crazy with your queries, Spring Data allows you two ways of doing so: the @Query annotation, or if that doesn't work, you can create custom repositories which are an extension that gives you the same power as if you write your own implementation from scratch.Plural
"Aggregated root" is a term often connected to the repository pattern. I don't know how you would use that with your definition of a repository.Brittaneybrittani
@ChristianStrempfer, I think the DAO pattern has been mostly dropped in practice in recent years and Repository has become the pattern (at least in Java). E.g. I hardly every create a DAOs nowadays. Like I said, both are practically the same, they are ways to access data. They are the same as DTO, VO or POJO ... names of the same thing, just named by different people. I think it is a good thing that one takes over, less confusion...Plural
Why is this is a bit different than the accepted answer? Am I missing something? "Repository could be implemented using DAO's, but you wouldn't do the opposite." However this says "If you want to use both, you would use the Repository in your DAO-s."Whensoever
T
133

DAO and Repository pattern are ways of implementing Data Access Layer (DAL). So, let's start with DAL, first.

Object-oriented applications that access a database, must have some logic to handle database access. In order to keep the code clean and modular, it is recommended that database access logic should be isolated into a separate module. In layered architecture, this module is DAL.

So far, we haven't talked about any particular implementation: only a general principle that putting database access logic in a separate module.

Now, how we can implement this principle? Well, one know way of implementing this, in particular with frameworks like Hibernate, is the DAO pattern.

DAO pattern is a way of generating DAL, where typically, each domain entity has its own DAO. For example, User and UserDao, Appointment and AppointmentDao, etc. An example of DAO with Hibernate: http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html.

Then what is Repository pattern? Like DAO, Repository pattern is also a way achieving DAL. The main point in Repository pattern is that, from the client/user perspective, it should look or behave as a collection. What is meant by behaving like a collection is not that it has to be instantiated like Collection collection = new SomeCollection(). Instead, it means that it should support operations such as add, remove, contains, etc. This is the essence of Repository pattern.

In practice, for example in the case of using Hibernate, Repository pattern is realized with DAO. That is an instance of DAL can be both at the same an instance of DAO pattern and Repository pattern.

Repository pattern is not necessarily something that one builds on top of DAO (as some may suggest). If DAOs are designed with an interface that supports the above-mentioned operations, then it is an instance of Repository pattern. Think about it, If DAOs already provide a collection-like set of operations, then what is the need for an extra layer on top of it?

Trajan answered 19/2, 2013 at 21:38 Comment(1)
"If DAOs already provide a collection-like set of operations, then what is the need for an extra layer on top of it?" Suppose you're modeling a pet shop and you have a table 'PetType' with different animals and their attributes (name: "Cat", type: "Mammal", etc.) referenced by a table 'Pet' of the concrete pets you have in the shop (name: "Katniss", breed: "Calico", etc.). If you want to add an animal of a type not already in the database, you could use a repository to group the two separate DAO calls (one to create PetType and the other for the Pet) in one method, avoiding coupling in DAOsPilcomayo
O
120

Frankly, this looks like a semantic distinction, not a technical distinction. The phrase Data Access Object doesn't refer to a "database" at all. And, although you could design it to be database-centric, I think most people would consider doing so a design flaw.

The purpose of the DAO is to hide the implementation details of the data access mechanism. How is the Repository pattern different? As far as I can tell, it isn't. Saying a Repository is different to a DAO because you're dealing with/return a collection of objects can't be right; DAOs can also return collections of objects.

Everything I've read about the repository pattern seems rely on this distinction: bad DAO design vs good DAO design (aka repository design pattern).

Owlet answered 8/7, 2012 at 17:7 Comment(3)
yep, totally agree, they are essentially the same. DAO sounds more DB related, but it's not. Same as Repository, it's just an abstraction used to hide where and how data is located.Plural
+1 For this statement. Frankly, this looks like a semantic distinction, not a technical distinction. The phrase Data Access Object doesn't refer to a "database" at all.Gudrun
The point when comparing Repositories and collections is not that they are dealing/returning collections of objects, but that Repositories behave as if they are collections themselves. For instance, in Java that means that a Repository does not have an update method because when you modify an object in a collection it is automatically updated (because Java collections only store references to objects).Buhr
S
19

Repository is more abstract domain oriented term that is part of Domain Driven Design, it is part of your domain design and a common language, DAO is a technical abstraction for data access technology, repository is concerns only with managing existing data and factories for creation of data.

Check these links:

Substitute answered 18/12, 2011 at 22:34 Comment(0)
R
15

A DAO allows for a simpler way to get data from storage, hiding the ugly queries.

Repository deals with data too and hides queries and all that but, a repository deals with business/domain objects.

A repository will use a DAO to get the data from the storage and uses that data to restore a business object.

For example, A DAO can contain some methods like that -

 public abstract class MangoDAO{
   abstract List<Mango>> getAllMangoes();
   abstract Mango getMangoByID(long mangoID);
}

And a Repository can contain some method like that -

   public abstract class MangoRepository{
       MangoDao mangoDao = new MangDao;

       Mango getExportQualityMango(){

       for(Mango mango:mangoDao.getAllMangoes()){
        /*Here some business logics are being applied.*/
        if(mango.isSkinFresh()&&mangoIsLarge(){
           mango.setDetails("It is an export quality mango");
            return mango;
           }
       }
    }
}

This tutorial helped me to get the main concept easily.

Rudbeckia answered 20/7, 2020 at 18:48 Comment(0)
L
8

The key difference is that a repository handles the access to the aggregate roots in a an aggregate, while DAO handles the access to entities. Therefore, it's common that a repository delegates the actual persistence of the aggregate roots to a DAO. Additionally, as the aggregate root must handle the access of the other entities, then it may need to delegate this access to other DAOs.

Lahomalahore answered 18/7, 2012 at 17:6 Comment(0)
C
5

Repository are nothing but well-designed DAO.

ORM are table centric but not DAO.

There's no need to use several DAO in repository since DAO itself can do exactly the same with ORM repositories/entities or any DAL provider, no matter where and how a car is persisted 1 table, 2 tables, n tables, half a table, a web service, a table and a web service etc. Services uses several DAO/repositories.

My own DAO, let's say CarDao only deal with Car DTO,I mean, only take Car DTO in input and only return car DTO or car DTO collections in output.

So just like Repository, DAO actually is an IoC, for the business logic, allowing persitence interfaces not be be intimidated by persitence strategies or legacies. DAO both encapsulates the persistence strategy and does provide the domaine-related persitence interface. Repository is just an another word for those who had not understood what a well-defined DAO actualy was.

Cardiogram answered 12/8, 2013 at 15:7 Comment(2)
First of all "ORM repositories/entities"? You mean ORM entities. There no such thing as a repository of ORMs. Second of all ORMs usually deal with entities only, ie. domain models. DAOs deal with tables directly and abstract data access. They return entities as well. Repositories are the highest abstraction, offering a collection interface to getting entities. A DAO can be a repository, ie. abstracting the actual storage engine, offering an interface to it and also offering a collection view of (cache) entities. A DAO can use an ORM to interface with the database and delegate entity ops.Eadie
Agree with @brokenthorn. The most crucial point in his comment is "Repositories are the highest abstraction," and this abstraction becomes a necessity when you want to protect your domain code from underlying database technology. ORM/Adapter/DB Driver concepts tend to leak into DAOs. If you have an application that supports more than one database technology, or if you want your app not to be locked to a database, using DAOs directly from the domain model is a no-go.Vilayet
G
5

DAO provides abstraction on database/data files or any other persistence mechanism so that, persistence layer could be manipulated without knowing its implementation details.

Whereas in Repository classes, multiple DAO classes can be used inside a single Repository method to get an operation done from "app perspective". So, instead of using multiple DAO at Domain layer, use repository to get it done. Repository is a layer which may contain some application logic like: If data is available in in-memory cache then fetch it from cache otherwise, fetch data from network and store it in in-memory cache for next time retrieval.

Galagalactagogue answered 14/3, 2019 at 4:15 Comment(0)
K
3

Try to find out if DAO or the Repository pattern is most applicable to the following situation : Imagine you would like to provide a uniform data access API for a persistent mechanism to various types of data sources such as RDBMS, LDAP, OODB, XML repositories and flat files.

Also refer to the following links as well, if interested:

http://www.codeinsanity.com/2008/08/repository-pattern.html

http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/

http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx

http://en.wikipedia.org/wiki/Domain-driven_design

http://msdn.microsoft.com/en-us/magazine/dd419654.aspx

Kra answered 19/12, 2011 at 6:9 Comment(0)
M
2

Per Spring documentation there is no clear difference:

The @Repository annotation is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO).

Maser answered 11/1, 2023 at 11:45 Comment(0)
L
2

If we consider the original definitions of both design patterns DAO and Repository appear very similar. The main difference is the dictionary and the source from which they came (Oracle vs. Fowler).

Quote:

  • DAO - "separates a data resource's client interface from its data access mechanisms" and "The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets."

  • Repository - "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." and "Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."

Based on these citations, both design patterns mediate communication between the domain layer and the data layer. Moreover, Repository is associated with ORM and on the contrary DAO is a more generic interface for accessing data from anywhere.

Livelihood answered 1/2, 2023 at 16:58 Comment(0)
T
1

DAOs might not always explicitly be related to Only DataBase,

It can be just an Interface to access Data, Data in this context might be accessed from DB/Cache or even REST (not so common these days, Since we can easily separate them in their respective Rest/IPC Clients),

Repo here in this approach be implemented by any of the ORM Solutions, If the underlying Cache/Repo Changes it'll not be propagated/impacts Service/Business Layers.

DAOs can accept/return Domain Types. Consider for a Student Domain, the associated DAO class will be StudentDao

StudentDao {

    StudentRepository, 
    StudentCache, 

    Optional<Student> getStudent(Id){

       // Use StudentRepository/StudentCache to Talk to DD & Cache 
       // Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
   
    }

    Student updateStudent(Student){

       // Use StudentRepository/StudentCache to Talk to DD & Cache 
       // Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
   
    }

}

DAOs can accept/return SubDomain Types. Consider a Student Domain, that has Sub Domain, say Attendance / Subject that will have a DAO class StudentDao,

StudentDao {

    StudentRepository, SubjectRepository, AttendanceRepository
    StudentCache, SubjectCache, AttendanceCache

    Set<Subject> getStudentSubject(Id){

       // Use SubjectRepository/SubjectCache to Talk to DD & Cache 
       
    }

    Student addNewSubjectToStudent(ID, Subject){

       // Use SubjectRepository/SubjectCache to Talk to DD & Cache 
      
   
    }

}
Trunk answered 25/10, 2022 at 5:55 Comment(0)
U
-1

in a very simple sentence: The significant difference being that Repositories represent collections, whilst DAOs are closer to the database, often being far more table-centric.

Union answered 17/11, 2018 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.