Personal

Sr. Developer

View on GitHub
16 April 2020

Apply Repository Pattern by Spring Data

by

We code for compiling.

We code for running.

We code for changing.

Repository Pattern

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Domain Driven Design is domain centric, and domain data persistance (is abstracted as data mapping) is mandatory for almost application.

Repository plays as an interface between client code and data mapping layers, hides complexity and isolates changes of data mapping layers from client code.

Diagram

Through repository, client code could access and persisten entity instances by collection-like and domain-centric interface. Because repository isolates changes of data mapping layers from client code, therefore it is easy to change data mapping layers implemenation. For example, it defines a repository interface and two implementations:

Diagram

When we changed the data mapping layer from JPA to MongoDB, it need not change any client code. Because client code depends on repository interface.

Diagram
Figure 1. JPA data mapping layer
Diagram
Figure 2. MongoDB data mapping layer

Data Mapper Pattern

In software engineering, the data mapper pattern is an architectural pattern. It was named by Martin Fowler in this 2003 book Patterns of Enterprise Application Architecture. The interface of an object conforming to this pattern would include functions such as Create, Read, Update, and Delete, that operate on objects that represent domain entity types in a data store.

A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in-memory data representation (the domain layer). The goal of the pattern is to keep the in-memory representation and the persistent data store independent of each other and the data mapper itself. The layer is composed of one or more mappers (or Data Access Objects), performing the data transfer. Mapper implementations vary in scope. Generic mappers will handle many different domain entity types, dedicated mappers will handle one or a few.

— Data mapper pattern
https://en.wikipedia.org/wiki/Data_mapper_pattern

The pattern descibes data access by descriptive approach. It defines elements of in-memory data representation and data store, and maps them. Take Object/Relation Mapping as an example, it defines elements of object represnetation:

  • class

  • object

  • field

and defines elements of Relational database:

  • table

  • record

  • column

and then maps them:

  • class maps to table

  • object maps to record

  • field maps to column

With data mapper pattern, application developer need not consider data access case by case, but describe the mapping of elements of in-memory and data store representations.

One Repository per Entity

Per Single-responsibility principle, one repository should only handle one entity.

The single-responsibility principle (SRP) is a computer-programming principle that states that every module or class should have responsiblity over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class, module or function. All its services should be narrowly aligned with that responsiblity. Robert C. Martin expresses the principle as "A class should have only one reason to change." although, because of confusion around the word "reason" he more recently stated "This principle is about people."

— Single-responsibility principle
https://en.wikipedia.org/wiki/Single-responsibility_principle

Keeping one repository per entity could benefit developer:

  • make repository small and clean

  • changing data store solution per entity independently

Spring Data

Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.

It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. This is an umbrella project which contains many subprojects that are specifiv to a given database. The projects are developed by working together with many of the companies and developers that are behind these exciting technologies.

— Spring Data
https://spring.io/projects/spring-data

The core of Spring Data is Repository. Repositories of Spring data are organized in interface/abstract class/implementation class pattern. Take Spring Data JPA as an example, it offers base interface JpaRepository and abstract class SimpleJpaRepository (SimpleJpaRepository technically is not declared as abstract, but it logically is used as abstract class). Application developer only needs to declare entity-specific repository interface, Spring Data will generate implementation class.

Diagram
Figure 3. Spring Data Repository

Predefined Repository Interface

Spring Data consists of core module Spring Data Commons and other data store specific modules. Spring Data is repository-centric. Spring Data Commons module defines a few common repository interfaces, other modules define more data store specific repository interfaces.

Spring Data Commons defines repository interfaces:

  • Repository, is a base and empty repository, does not declare any methods.

    Diagram
    1. CrudReposority, declares simple Create/Read/Update/Delete methods.

      Diagram
    2. PagingAndSortingRepository, inherit simple Create/Read/Update/Delete methods and plus pagination and sorting support.

      Diagram
    3. ReactiveCrudRepository, TBD

    4. ReactiveSortingRepository, TBD

    5. RevisionRepository, TBD

      Diagram
    6. RxJava2CrudRepository, TBD

    7. RxJava2SortingRepository, TBD

Deriving the Query from the Method Name

TBD

Using a Manually Defined Query

TBD

tags: spring-boot - spring - spring-data - repository-pattern