Difference Between Repository Pattern and DAO in Java
- Data Access Object Pattern
- Repository Pattern
- Difference Between the Data Access Object (DAO) and Repository Patterns in Java
- Difference Between the DAO and Repository Patterns Implementation
Today, we will learn about the Data Access Object (DAO) and repository patterns. This article also educates about the differences between them.
Data Access Object Pattern
This pattern is the data persistence’s abstraction, also considered closer to underlying storage, which is mostly table-centric. That’s why, most of the time, the Data Access Objects (DAOs) match the database tables, permitting the most straightforward method to retrieve and send data from the storage while hiding the ugly queries.
Repository Pattern
A repository pattern is a procedure to retrieve stored data from our application that hides every aspect of a data storage system. Following is the repository interface that lets us look up one user
by its username
.
interface UserRepository {
User findUserByUsername(Username name);
}
This can have one or multiple implementations based on our storage technology - for instance, MySQL, Amazon DynamoDB, Web Service, Oracle, or others.
We can also say that the repository pattern is a design pattern that isolates the data source from the rest of an application. The repository mediates between the data sources (such as Web Services and Persistent Models) and the rest of an application.
Following is the graphical representation of the repository pattern’s use.
You understand right that the repository is similar to the Data Access Object (DAO) but an abstraction that hides all the logic that is being used for retrieving the data from business logic.
It behaves like a wrapper around the Model and is responsible for accessing data from a persistent store. The benefit of using a repository is that it separates the precise details of how our stuff will store from the application that is using it.
This is extremely important for testing because we can write stub code that will always return a User
but does not access the database. It frees us from various issues and lets us write the fast unit test for our application code, which will not depend on the stored data.
Difference Between the Data Access Object (DAO) and Repository Patterns in Java
The primary difference is that the repository returns the objects only that are understandable by a calling layer. Mostly, the repository is used by a business layer, and thus, it outputs the business objects.
On the other side, the Data Access Object returns the data that might/might not be the whole business object. It means the data is not a valid business concept.
If our business objects are the data structures only, then it can hint that we have the modeling problem. It means bad design while a repository will make more sense with at least encapsulated objects properly.
If we are only loading or saving the data structures, then most probably, we do not need to have a repository. The Object Relational Mapping (ORM) is enough.
A repository pattern is the best solution if we have to deal with a business object composed of various other objects (an aggregate), and this specific object requires all its parts to be consistent (aggregate root).
It is because it abstracts complete persistence information. Our application asks for a Product
only, and the repository returns that as a whole; it does not matter how many queries/tables are needed to restore an object.
Remember that the business object is not an Object Relational Mapping (ORM) entity. It may be from a technical point of view, but considering the design, one models the business stuff, and the other models the persistence stuff.
Most of the time, there is no direct compatibility.
Here are some situations where we prefer to use a Repository Pattern:
- It is used in a System where we have many heavy queries.
- We use repository patterns to avoid duplicate queries.
- It is used between the Data Storage and the domains(entity).
- It is also used for searching and removing an element using the entity’s specification for which the repository is created.
Now, let’s understand this difference via code implementation.
Difference Between the DAO and Repository Patterns Implementation
Let’s start with the implementation of the Data Access Object pattern.
Data Access Object Pattern Implementation
Here, we need to have three classes that are listed below:
- A basic
Employee
domain class - The
EmployeeDAO
interface that provides easy CRUD operations for anEmployee
domain - An
EmployeeDAOImplementation
class that implements theEmployeeDAO
interface
Example Code (Employee
Class):
public class Employee {
private Long id;
private String employeeCode;
private String firstName;
private String email;
// write your getters/setters
}
Example Code (EmployeeDAO
Interface):
public interface EmployeeDAO {
void create(Employee employee);
Employee read(Long id);
void update(Employee employee);
void delete(String employeeCode);
}
Example Code (EmployeeDAOImplementation
Class):
public class EmployeeDAOImplementation implements EmployeeDAO {
private final EntityManager entityManager;
@Override
public void create(Employee employee) {
entityManager.persist(employee);
}
@Override
public Employee read(long id) {
return entityManager.find(Employee.class, id);
}
// ... continue with remaining code
}
We are using the JPA EntityManager Interface to communicate with the underlying storage. Also, provide the data access mechanism for the Employee
domain.
Repository Pattern Implementation
This pattern encapsulates the storage, search behavior, and retrieval, simulating the collection of objects. Like DAO, it also hides queries and deals with data but sits at a higher level closer to the application’s business logic.
A repository can also use the DAO to fetch the data from a database. Also, it can populate the domain object or prepare data from the domain and then send it to the storage system using DAO for persistence.
Here, we need the following classes:
- An
EmployeeRepository
Interface - An
EmployeeRepositoryImplementation
Class
Example Code (EmployeeRepository
Interface):
public interface EmployeeRepository {
Employee get(Long id);
void add(Employee employee);
void update(Employee employee);
void remove(Employee employee);
}
Example Code (EmployeeRepositoryImplementation
Class):
public class EmployeeRepositoryImplementation implements EmployeeRepository {
private EmployeeDAOImplementation employeeDAOImplementation;
@Override
public Employee get(Long id) {
Employee employee = employeeDAOImplementation.read(id);
return employee;
}
@Override
public void add(Employee employee) {
employeeDAOImplementation.create(employee);
}
// ... continue with remaining code
}
Here, we use the EmployeeDAOImplementation
to retrieve/send data from a database. So, we can say that the implementation of the repository and DAO look similar.
It is because the Employee
class is the anemic domain and a repository is only another layer over the data-access layer (DAO); however, a repository is the best way to implement the business use case. In comparison, the data access object looks good candidate for accessing the data.