# Org / Springframework / Samples / Petclinic

## Overview

`org.springframework.samples.petclinic` is the top-level application area for the Petclinic sample. It brings together the shared domain model, owner-management flows, veterinarian listings, and system-wide web configuration that make the sample feel like a complete clinic application rather than a set of isolated packages.

This appears to be a classic Spring Boot sample built around a small but coherent business domain: owners bring pets to the clinic, pets receive visits, and vets are listed as part of the clinic staff. The package set also includes cross-cutting infrastructure such as locale handling, caching, and top-level navigation so the application behaves like a polished end-to-end demo.

## Sub-module Guide

### `model`

The `model` package provides shared base entities such as `BaseEntity`, `NamedEntity`, and `Person`. These classes are the common inheritance foundation used by the rest of the domain: they centralize identity, names, and validation rules so feature packages do not repeat them.

The rest of the system depends on this package for consistent persistence and validation behavior. In practice, `owner` and `vet` build on these base types, while `service` tests confirm that the model behaves correctly under real JPA and validation infrastructure.

### `owner`

The `owner` package appears to implement the main owner-facing workflow. It includes the aggregate root (`Owner`), nested domain objects (`Pet`, `Visit`, `PetType`), repositories, form helpers, validators, and MVC controllers.

This package is where the clinic domain becomes interactive. Controllers load owners, mutate their pets and visits, and save through the owner aggregate rather than persisting children independently. That relationship matters because it keeps ownership logic and lifecycle management in one place.

### `vet`

The `vet` package owns the veterinarian side of the domain. It defines `Vet` and `Specialty`, exposes `VetRepository`, and provides `VetController` plus a serialization wrapper for browser and API responses.

It connects directly to the clinic's read-only staff listing use case. Compared with `owner`, it is smaller and more focused: the package mostly serves read flows, caching, pagination, and serialization concerns around vet data.

### `system`

The `system` package contains the application-wide web and infrastructure pieces that sit outside the business aggregates. It wires the welcome page, locale switching, cache creation, and a deliberate crash endpoint used for error-page demonstrations and tests.

This package acts like the shell around the domain. It does not model clinic records, but it shapes how the whole application starts, routes requests, handles localization, and demonstrates failure behavior.

### `service`

The `service` package is test-focused rather than production-service focused. It validates repository and aggregate behavior across owners, pets, visits, pet types, and vets using real persistence infrastructure.

This package is the system's persistence confidence layer. It confirms that the domain model, repositories, cascading rules, and fixture data work together the way the application expects.

## Key Patterns and Architecture

### Layered application structure

The packages divide responsibilities along familiar Spring lines:

- `model` defines reusable persistence and validation foundations.
- `owner` and `vet` implement feature-specific domain, repositories, and controllers.
- `system` contributes shared web and infrastructure configuration.
- `service` verifies the data layer and relationships end to end.

This separation keeps the domain readable while still allowing the application to share infrastructure and base classes.

### Aggregate-oriented data flow

The clearest structural pattern is the owner aggregate. The `owner` package treats `Owner` as the persistence boundary for related pets and visits. Controllers and tests mutate the owner graph and then save the owner back through its repository.

That pattern reduces the need for separate child-entity write APIs and keeps business rules close to the owning entity. It also makes the web layer simpler because handlers can work with one root object instead of coordinating multiple persistence paths.

### Read-optimized vet listing

The `vet` package uses a lighter-weight pattern: a read-only repository, caching, pagination, and a wrapper object for serialization. This appears to optimize the most common vet use cases without introducing unnecessary write complexity.

### Cross-cutting web support

The `system` package adds application-wide concerns that every feature benefits from:

- root request routing,
- session-based locale switching,
- cache bootstrapping,
- and a controlled error endpoint for demonstrations and tests.

These pieces are small on their own, but they define the application experience at a higher level than the feature packages.

### Interaction diagram

```mermaid
flowchart TD
  PetclinicApp["PetClinicApplication"] --> System["system"]
  PetclinicApp --> Owner["owner"]
  PetclinicApp --> Vet["vet"]
  PetclinicApp --> Model["model"]
  PetclinicApp --> ServiceTests["service tests"]
  System --> WelcomeController["WelcomeController"]
  System --> WebConfiguration["WebConfiguration"]
  System --> CacheConfiguration["CacheConfiguration"]
  System --> CrashController["CrashController"]
  Owner --> OwnerController["OwnerController"]
  Owner --> PetController["PetController"]
  Owner --> VisitController["VisitController"]
  Owner --> OwnerRepository["OwnerRepository"]
  Owner --> PetTypeRepository["PetTypeRepository"]
  Vet --> VetController["VetController"]
  Vet --> VetRepository["VetRepository"]
  Model --> BaseEntity["BaseEntity"]
  Model --> NamedEntity["NamedEntity"]
  Model --> Person["Person"]
  ServiceTests --> OwnerRepository
  ServiceTests --> VetRepository
  OwnerController --> OwnerRepository
  PetController --> OwnerRepository
  PetController --> PetTypeRepository
  VisitController --> OwnerRepository
  VetController --> VetRepository
```

## Dependencies and Integration

### Internal dependencies

The primary internal dependency is from feature packages back to the shared model package.

- `org.springframework.samples.petclinic.model` provides `BaseEntity`, `NamedEntity`, and `Person`.
- `org.springframework.samples.petclinic.owner` builds on those types for owner, pet, visit, and pet type behavior.
- `org.springframework.samples.petclinic.vet` builds on them for veterinarian and specialty data.
- `org.springframework.samples.petclinic.service` uses those same domain types to validate repository behavior.

The evidence also shows direct package dependency links from the root package to `vet` and `model`, which fits the idea that the application bootstrap and runtime hints need to know about those areas.

### Framework integration

Across the sub-modules, the application uses several Spring and Jakarta features together:

- Spring Boot application startup and runtime hints,
- Spring MVC controllers and views,
- Spring Data JPA repositories,
- Bean Validation,
- caching via JCache,
- locale resolution and request interception,
- and serialization support for API-style responses.

### Application entry points and tests

The root package includes the main bootstrapping and test scaffolding classes:

- `PetClinicApplication` starts the application.
- `PetClinicRuntimeHints` appears to register runtime metadata needed by the application in native or reflection-sensitive environments.
- `PetClinicIntegrationTests`, `MySqlIntegrationTests`, and `PostgresIntegrationTests` exercise the application against different database setups.
- `MysqlTestApplication` supports the MySQL-specific integration test path.

These classes are the connective tissue between the feature packages and the environment they run in.

## Notes for Developers

- The codebase appears intentionally compact, but the module boundaries are meaningful. Changes in one package often ripple into others because controllers, repositories, and shared base entities are tightly coupled.
- `owner` is the most relationship-heavy area. If you change pets, visits, or owner persistence rules, expect updates to controllers and persistence tests.
- `vet` is read-optimized and cache-aware. If you change the vet listing shape or serialization contract, check cache behavior and controller tests.
- `system` is cross-cutting. Seemingly small changes there can affect startup, routing, i18n, cache initialization, or error handling across the whole application.
- `service` tests act as a safety net for the persistence model. When fixture data, cascade settings, or repository methods change, update those tests deliberately.
- The package structure suggests a sample application rather than a large enterprise system, so clarity and consistency matter more than abstraction for its own sake.

## How the Pieces Work Together

1. `PetClinicApplication` starts the Spring Boot application.
2. `system` contributes top-level routing, caching, and locale support.
3. `owner` handles the main clinic workflow for owners, pets, and visits.
4. `vet` exposes veterinarian information for both UI and serialized clients.
5. `model` supplies the shared entity base classes that make the domain consistent.
6. `service` verifies that the persistence layer and relationships still behave as expected.

Taken together, the sub-modules form a small but complete clinic management sample with shared persistence foundations, a strong owner aggregate, read-optimized vet listings, and application-level infrastructure that ties the experience together.

### High-level interaction diagram

```mermaid
sequenceDiagram
participant App as PetClinicApplication
participant Sys as system
participant Own as owner
participant Vet as vet
participant Mod as model
App ->> Sys - configure web routing, locale, cache, and error handling
App ->> Own - load owner workflows
App ->> Vet - load vet listings and specialties
Own ->> Mod - reuse shared entities and validation base classes
Vet ->> Mod - reuse shared entities and validation base classes
```

## Referenced Source Files

- [src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java](src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java)
- [src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java](src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java)
- [src/main/java/org/springframework/samples/petclinic/package-info.java](src/main/java/org/springframework/samples/petclinic/package-info.java)
- [src/test/java/org/springframework/samples/petclinic/MySqlIntegrationTests.java](src/test/java/org/springframework/samples/petclinic/MySqlIntegrationTests.java)
- [src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java](src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java)
- [src/test/java/org/springframework/samples/petclinic/PetClinicIntegrationTests.java](src/test/java/org/springframework/samples/petclinic/PetClinicIntegrationTests.java)
- [src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java](src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java)
