Difference Between Repository Pattern and DAO in Java

Mehvish Ashiq Oct 12, 2023
  1. Data Access Object Pattern
  2. Repository Pattern
  3. Difference Between the Data Access Object (DAO) and Repository Patterns in Java
  4. Difference Between the DAO and Repository Patterns Implementation
Difference Between Repository Pattern and DAO in Java

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.

difference between repository pattern and dao in java - repository visualization

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:

  1. A basic Employee domain class
  2. The EmployeeDAO interface that provides easy CRUD operations for an Employee domain
  3. An EmployeeDAOImplementation class that implements the EmployeeDAO 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:

  1. An EmployeeRepository Interface
  2. 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.

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook