Implementing Repository Pattern

1. Implementing Repository Interface

Example: Domain repository contract

public interface CustomerRepository {
    Optional<Customer> findById(CustomerId id);
    Optional<Customer> findByEmail(Email email);
    void save(Customer customer);
    void delete(CustomerId id);
    Page<Customer> search(CustomerFilter filter, Pageable pageable);
}

2. Implementing Generic Repository

Example: Spring Data style

public interface CrudRepository<T, ID> {
    Optional<T> findById(ID id);
    List<T> findAll();
    T save(T entity);
    void deleteById(ID id);
    long count();
    boolean existsById(ID id);
}
Warning: Avoid exposing generic CRUD on domain repositories — only what makes sense for the aggregate.

3. Implementing Specification Pattern

Example: Spring Data JPA Specification

public class OrderSpecs {
    public static Specification<Order> byStatus(String s) {
        return (root, q, cb) -> cb.equal(root.get("status"), s);
    }
    public static Specification<Order> placedAfter(Instant t) {
        return (root, q, cb) -> cb.greaterThan(root.get("placedAt"), t);
    }
}
repo.findAll(byStatus("PAID").and(placedAfter(yesterday)));

4. Implementing Unit of Work Pattern

ElementImplementation
Spring@Transactional ⇒ EntityManager session
TrackingHibernate dirty checking
FlushAuto on commit; manual via em.flush()

5. Implementing Query Object Pattern

FormDetail
Criteria builderType-safe, programmatic
QueryDSLFluent type-safe DSL
jOOQSQL-like fluent API
Plain DTOFilter object passed to repo

6. Implementing Data Access Layer Abstraction

GoalMechanism
Hide ORMDomain depends on interface
Swap implJPA → MongoDB without service changes
TestIn-memory fake repo

7. Implementing Repository Methods

NamingSpring Data Convention
find byfindBy<Field>
multiple criteriafindByXAndY
orderingfindByXOrderByY[Asc|Desc]
existenceexistsBy*
countingcountBy*
deletingdeleteBy*

8. Implementing Pagination in Repository

Example: Paged query

Page<Order> page = orderRepo.findByStatus("OPEN",
    PageRequest.of(pageNum, size, Sort.by("placedAt").descending()));

9. Implementing Repository Exception Handling

ScenarioAction
Not foundReturn Optional.empty()
Constraint violationTranslate to domain exception
Connection errorWrap as IntegrationException
Spring@Repository auto-translates

10. Implementing Custom Repository Implementations

Example: Spring Data custom impl

public interface OrderRepoCustom { List<OrderSummary> reportFor(Instant from); }

public class OrderRepoCustomImpl implements OrderRepoCustom {
    @PersistenceContext private EntityManager em;
    public List<OrderSummary> reportFor(Instant from) {
        return em.createQuery("...", OrderSummary.class)
                 .setParameter("f", from).getResultList();
    }
}

public interface OrderRepository extends JpaRepository<Order, Long>, OrderRepoCustom {}

11. Implementing Repository Factory

Use CaseDetail
Multi-tenantPer-tenant connection
Shard routingPick repo by key
Read replicaRoute reads to replica

12. Implementing Read vs Write Repository

Write Repository

  • Loads aggregates
  • Saves aggregates
  • Tx boundary
  • Returns domain types

Read Repository

  • Optimized projections
  • Returns DTOs
  • Read-only tx
  • May use replica