# Org / Springframework / Samples / Petclinic / Vet

## Overview

The `org.springframework.samples.petclinic.vet` package contains the veterinarian-facing part of Petclinic: the vet domain model, a repository abstraction for loading vets, and a web controller that exposes vet data in both HTML and XML/JSON-friendly forms. It exists to support the staff-facing view of the application, where users can browse veterinarians and their specialties.

This module is intentionally small, but it sits at an important boundary. It connects the persistence layer to the web tier, and it also contains lightweight JAXB-friendly wrapper types so the same data can be rendered for browser views and structured responses.

## Key Classes and Interfaces

### [Specialty](src/main/java/org/springframework/samples/petclinic/vet/Specialty.java)

`Specialty` models a veterinarian specialty such as dentistry or radiology. It is a JPA entity mapped to the `specialties` table and inherits shared identity and name fields from `NamedEntity`.

What it does:
- Represents a single specialty record in the data model.
- Provides the named value object used by `Vet` to describe areas of practice.

Why it exists:
- The vet domain needs a normalized way to represent specialties that can be shared across multiple vets.
- Keeping specialty as its own entity makes the many-to-many relationship between vets and specialties explicit.

There are no custom methods in this class; its behavior comes entirely from `NamedEntity` and JPA annotations.

### [Vet](src/main/java/org/springframework/samples/petclinic/vet/Vet.java)

`Vet` is the core domain object for this module. It extends `Person`, so it inherits personal identity fields such as first name, last name, and id, and it adds a set of specialties.

Design role:
- Represents a veterinarian in the application domain.
- Serves as the aggregate root for the vet-specialty relationship.
- Exposes a sorted list view of specialties for serialization and presentation.

Persistence mapping:
- Annotated as a JPA entity mapped to the `vets` table.
- Uses `@ManyToMany(fetch = FetchType.EAGER)` to load specialties together with the vet.
- Uses the `vet_specialties` join table with `vet_id` and `specialty_id` join columns.

Key methods:
- `getSpecialtiesInternal()` — protected helper that lazily initializes the backing `Set<Specialty>`.
  - Returns the mutable internal set.
  - Ensures callers never see a null collection.
- `getSpecialties()` — returns a sorted `List<Specialty>`.
  - Sorts specialties by name using `Comparator.comparing(NamedEntity::getName)`.
  - Returns a new list rather than the raw set.
  - Annotated with `@XmlElement`, which makes it suitable for XML/JAXB serialization.
- `getNrOfSpecialties()` — returns the number of specialties.
  - Uses the backing set size.
  - Useful for UI display and summary views.
- `addSpecialty(Specialty specialty)` — adds a specialty to the vet.
  - Mutates the internal set.
  - No duplicate entries are allowed at the set level.

Why the implementation looks this way:
- The internal collection is a `Set` to prevent duplicates in the domain model.
- The public accessor returns a sorted `List` so callers get stable ordering for display and serialization.
- Lazy initialization avoids null checks throughout the codebase.

### [VetRepository](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java)

`VetRepository` defines the data-access contract for loading vets. It extends Spring Data's `Repository<Vet, Integer>` and declares only the operations this module needs.

Design role:
- Abstracts persistence behind a narrow repository interface.
- Provides both full-list and paginated access patterns.
- Adds caching and transactional semantics around read operations.

Key methods:
- `findAll()` — retrieves all vets as a `Collection<Vet>`.
  - Marked `@Transactional(readOnly = true)`.
  - Marked `@Cacheable("vets")`, so repeated reads can be served from cache.
  - Throws `DataAccessException` for persistence failures.
- `findAll(Pageable pageable)` — retrieves a paginated `Page<Vet>`.
  - Also read-only, also cached under `vets`.
  - Used by the HTML view to support paging.

Why it matters:
- The controller does not depend on a concrete repository implementation.
- The repository interface can be backed by Spring Data JPA or another mechanism while preserving the same contract.

### [VetController](src/main/java/org/springframework/samples/petclinic/vet/VetController.java)

`VetController` is the web entry point for the vet module. It serves an HTML page at `/vets.html` and a structured response at `/vets`.

Design role:
- Bridges HTTP requests to repository calls.
- Prepares model attributes for the `vets/vetList` view.
- Wraps responses in `Vets` for easier XML/JSON marshalling.

Key methods:
- Constructor `VetController(VetRepository vetRepository)`
  - Injects the repository dependency.
  - Keeps the controller testable and thin.
- `showVetList(@RequestParam(defaultValue = "1") int page, Model model)`
  - Handles `GET /vets.html`.
  - Builds a `Vets` wrapper, loads the requested page, and populates the model.
  - Returns the view name `vets/vetList`.
  - The method creates a wrapper object even though the returned HTML view mainly uses model attributes; the inline comment indicates this is to simplify object-XML mapping.
- `addPaginationModel(int page, Page<Vet> paginated, Model model)`
  - Adds pagination metadata to the model: `currentPage`, `totalPages`, `totalItems`, and `listVets`.
  - Returns the same view name used by `showVetList()`.
- `findPaginated(int page)`
  - Uses a fixed page size of 5.
  - Converts the 1-based request page into a 0-based `PageRequest`.
  - Calls `vetRepository.findAll(pageable)`.
- `showResourcesVetList()`
  - Handles `GET /vets` and returns `@ResponseBody` data.
  - Loads all vets, wraps them in `Vets`, and returns the wrapper for JSON or XML serialization.

How the two endpoints differ:
- `/vets.html` is the browser-oriented paginated view.
- `/vets` is the resource-oriented endpoint for structured serialization.

### [Vets](src/main/java/org/springframework/samples/petclinic/vet/Vets.java)

`Vets` is a simple JAXB-friendly wrapper around a list of `Vet` objects.

Why it exists:
- JAXB and similar marshalling mechanisms work more cleanly with a single root object than with a bare collection.
- The controller uses this wrapper to make XML/JSON output more predictable.

Key method:
- `getVetList()`
  - Lazily initializes the list.
  - Returns the mutable backing list.
  - Annotated with `@XmlElement`, so each vet is emitted as an element in serialized output.

This class is intentionally minimal; it is mainly a transport wrapper rather than a behavior-rich domain object.

## How It Works

### HTML vet list request flow

1. A client requests `GET /vets.html?page=1`.
2. `VetController.showVetList()` receives the request and defaults the page parameter to `1` if omitted.
3. `findPaginated(1)` converts the page number into a `PageRequest` with page size `5`.
4. `VetRepository.findAll(pageable)` returns a `Page<Vet>`.
5. `addPaginationModel()` copies the page content and pagination metadata into the `Model`.
6. Spring renders the `vets/vetList` view.

Important detail:
- Page numbering is user-facing and starts at 1, while the underlying `PageRequest` is zero-based.

### Structured vet list request flow

1. A client requests `GET /vets` with JSON or XML acceptance headers.
2. `VetController.showResourcesVetList()` loads all vets from the repository.
3. The method places them into a `Vets` wrapper.
4. Spring serializes the wrapper via message conversion or JAXB.

Important detail:
- Returning `Vets` instead of `Collection<Vet>` makes the response root element explicit and keeps marshalling simple.

### Vet specialty handling

1. A `Vet` instance stores specialties in a `Set<Specialty>`.
2. `addSpecialty()` mutates that set.
3. `getSpecialties()` exposes the specialties as a sorted list.
4. `getNrOfSpecialties()` reports the count.

This design keeps the internal model deduplicated while producing stable output for views and serialization.

## Data Model

The package centers on three main model types:

- `Vet`
  - Represents a veterinarian.
  - Extends `Person` from the shared model layer.
  - Owns a many-to-many relationship to `Specialty`.
- `Specialty`
  - Represents a named area of practice.
  - Extends `NamedEntity`.
- `Vets`
  - Wrapper type containing a list of vets for serialization.

Relationship summary:
- One vet can have many specialties.
- One specialty can be associated with many vets.
- The join table `vet_specialties` stores the relationship.

Mermaid diagram:

```mermaid
flowchart LR
Module["org.springframework.samples.petclinic.vet"] --> Specialty["Specialty"]
Module["org.springframework.samples.petclinic.vet"] --> Vet["Vet"]
Module["org.springframework.samples.petclinic.vet"] --> VetController["VetController"]
Module["org.springframework.samples.petclinic.vet"] --> VetRepository["VetRepository"]
Module["org.springframework.samples.petclinic.vet"] --> Vets["Vets"]
Vet["Vet"] --> Person["Person"]
Specialty["Specialty"] --> NamedEntity["NamedEntity"]
VetController["VetController"] --> VetRepository["VetRepository"]
VetController["VetController"] --> Vets["Vets"]
VetController["VetController"] --> Model["Model"]
VetRepository["VetRepository"] --> Page["Page<Vet>"]
Vets["Vets"] --> Vet["Vet"]
```

## Dependencies and Integration

This module depends on several shared parts of the application and Spring infrastructure:

- `org.springframework.samples.petclinic.model.Person`
  - Base class for `Vet`.
  - Supplies common person fields and behavior.
- `org.springframework.samples.petclinic.model.NamedEntity`
  - Base class for `Specialty` and used by `Vet` sorting logic.
- Spring Web MVC
  - `@Controller`, `@GetMapping`, `Model`, and `@ResponseBody` drive the web layer.
- Spring Data
  - `Page`, `Pageable`, and `PageRequest` provide pagination.
  - `Repository` defines the repository contract.
- Spring Cache
  - `@Cacheable("vets")` caches both repository methods.
- Jakarta Persistence
  - JPA annotations map `Vet` and `Specialty` to database tables.
- JAXB
  - `@XmlRootElement` and `@XmlElement` support XML marshalling.

The tests show how these integrations are expected to behave:
- `VetControllerTests` exercises the MVC endpoints using `MockMvc` and a mocked repository.
- `VetTests` verifies that `Vet` remains serializable.

## Notes for Developers

- `Vet` uses a lazy-initialized `Set` internally, so code that adds specialties should use `addSpecialty()` or `getSpecialtiesInternal()` rather than assuming the field is initialized.
- `getSpecialties()` returns a sorted copy-like view as a `List`, not the raw backing set. If you need mutation, work through the internal set or `addSpecialty()`.
- The controller page size is hard-coded to `5`. If you change this value, update any tests or UI assumptions that depend on it.
- `findPaginated()` expects 1-based page numbers from the web layer. Passing `0` or negative numbers would produce invalid `PageRequest` values.
- `@Cacheable("vets")` is applied to both repository query methods. If vet data changes and cache eviction is not handled elsewhere, callers may see stale results.
- The `Vets` wrapper is part of the module’s API shape for serialization. Changing it will affect XML/JSON output and tests that assert on the `vetList` property.
- `VetControllerTests` expects the JSON response to expose a top-level `vetList` field and the HTML flow to use the `vets/vetList` view.

## Tests

Relevant tests in this package document the intended behavior:

- [VetControllerTests](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java)
  - Verifies the HTML endpoint resolves successfully.
  - Verifies the resource endpoint returns JSON with the expected structure.
- [VetTests](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java)
  - Verifies that `Vet` survives Java serialization with its key fields intact.

Together, these tests confirm the package’s primary responsibilities: retrieving vets, rendering them in the web layer, and preserving the domain model across serialization boundaries.
