# Org / Springframework / Samples / Petclinic / Vet

## Overview

This module appears to define the veterinarian-facing portion of Petclinic: the vet domain model, a repository abstraction for loading vets, and a controller that exposes both HTML and JSON/XML-friendly views of the data. It exists to support listing veterinarians along with their specialties, which is a core read-only browsing use case in the sample application.

The package is intentionally small and focused. The main design pattern is simple: `VetRepository` provides access to `Vet` entities, `VetController` turns that data into web responses, and `Vets` exists as a wrapper type for marshalling collections cleanly to XML or JSON.

## Key Classes and Interfaces

### `Vet`

- Code: [src/main/java/org/springframework/samples/petclinic/vet/Vet.java](src/main/java/org/springframework/samples/petclinic/vet/Vet.java)
- Role: JPA entity representing a veterinarian.
- Inheritance: extends [`Person`](src/main/java/org/springframework/samples/petclinic/model/Person.java), so it inherits common person fields such as name and identity behavior.

`Vet` is the core domain object in this package. It maps to the `vets` table and carries a many-to-many relationship to `Specialty` through the `vet_specialties` join table. The relationship is eagerly fetched, which means a vet's specialties are loaded immediately with the vet record rather than lazily later in the request.

Key methods:

- `getSpecialtiesInternal()`
  - Returns the backing `Set<Specialty>` used by the entity.
  - Lazily initializes the set to an empty `HashSet` if needed.
  - This method is protected and exists to keep the public API sorted and collection-safe while still allowing mutation.
- `getSpecialties()`
  - Returns a sorted `List<Specialty>` for external use.
  - Sorts specialties by the inherited `name` field via `NamedEntity::getName`.
  - Annotated with `@XmlElement`, which makes it the exposed accessor when the object is marshalled.
- `getNrOfSpecialties()`
  - Returns the number of specialties currently attached to the vet.
  - Useful for display logic or summaries.
- `addSpecialty(Specialty specialty)`
  - Adds a specialty to the backing set.
  - The set semantics prevent duplicate relationships in memory.

Design note: the class stores specialties as a `Set` internally, but exposes them as a sorted `List` externally. That gives stable output ordering while keeping the persistence model suitable for many-to-many associations.

### `Specialty`

- Code: [src/main/java/org/springframework/samples/petclinic/vet/Specialty.java](src/main/java/org/springframework/samples/petclinic/vet/Specialty.java)
- Role: JPA entity for a veterinarian specialty such as dentistry or radiology.
- Inheritance: extends [`NamedEntity`](src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java), so it behaves like a named lookup-style entity.

`Specialty` is intentionally minimal. It exists mainly to model the other side of the vet/specialty relationship and to reuse shared identity and `name` behavior from `NamedEntity`.

Because the class contains no additional fields or methods, its main purpose is structural: it lets vets be associated with categorized skills and makes those associations persistable through JPA.

### `VetRepository`

- Code: [src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java)
- Role: repository abstraction for loading vets from the data store.

`VetRepository` is declared as a Spring Data `Repository<Vet, Integer>` and defines only two read methods. It does not implement persistence logic itself; instead, it relies on Spring Data conventions and infrastructure.

Key methods:

- `findAll()`
  - Returns all vets as a `Collection<Vet>`.
  - Marked `@Transactional(readOnly = true)` because it is a read-only query.
  - Marked `@Cacheable("vets")`, so repeated calls can be served from the `vets` cache.
- `findAll(Pageable pageable)`
  - Returns a paginated `Page<Vet>`.
  - Also read-only and cached.
  - Used by the controller to power the HTML paginated list.

This repository is the module's main integration point with the persistence layer. It is deliberately narrow: the package only needs read access for the vet listing features shown here.

### `VetController`

- Code: [src/main/java/org/springframework/samples/petclinic/vet/VetController.java](src/main/java/org/springframework/samples/petclinic/vet/VetController.java)
- Role: web controller for vet listing endpoints.

`VetController` exposes two views of the same underlying data:

- `/vets.html` returns the HTML page used by the UI.
- `/vets` returns a `Vets` object as a response body, which is suitable for JSON/XML serialization.

Key methods:

- `VetController(VetRepository vetRepository)`
  - Constructor injection of the repository dependency.
  - Keeps the controller easy to test by allowing the repository to be mocked.
- `showVetList(@RequestParam(defaultValue = "1") int page, Model model)`
  - Handles `GET /vets.html`.
  - Builds a `Vets` wrapper, loads a paginated page of vets, and adds the page state to the MVC `Model`.
  - Returns the logical view name `vets/vetList`.
  - The inline comment explains that `Vets` is used instead of a raw collection to simplify XML mapping.
- `addPaginationModel(int page, Page<Vet> paginated, Model model)`
  - Adds pagination attributes to the model: `currentPage`, `totalPages`, `totalItems`, and `listVets`.
  - Returns the same view name used by the HTML endpoint.
- `findPaginated(int page)`
  - Creates a `PageRequest` with a fixed page size of 5.
  - Converts the incoming 1-based page number to Spring Data's 0-based page index.
  - Delegates to `vetRepository.findAll(pageable)`.
- `showResourcesVetList()`
  - Handles `GET /vets` and returns `@ResponseBody Vets`.
  - Wraps all vets in a `Vets` object for easier object-to-JSON or object-to-XML conversion.

Design note: the controller keeps response shaping in the web layer and leaves the repository focused on data access. The two endpoints differ only in representation, not in the underlying domain data.

### `Vets`

- Code: [src/main/java/org/springframework/samples/petclinic/vet/Vets.java](src/main/java/org/springframework/samples/petclinic/vet/Vets.java)
- Role: wrapper object for a list of vets.

`Vets` exists mainly for marshalling. Rather than exposing a bare `List<Vet>`, the module uses a root XML/JSON-friendly container with a named `vetList` property.

Key method:

- `getVetList()`
  - Lazily initializes and returns the internal `List<Vet>`.
  - Annotated with `@XmlElement`, so the list is emitted as a named element when marshalled.

This class is a classic wrapper DTO: small, mutable, and purpose-built for serialization frameworks.

## How It Works

### HTML vet list flow

1. A client requests `GET /vets.html?page=1`.
2. `VetController.showVetList()` receives the request and uses the default page value of `1` if none is provided.
3. The controller calls `findPaginated(page)`, which creates a `PageRequest` of size 5 and delegates to `VetRepository.findAll(pageable)`.
4. The repository returns a `Page<Vet>`, which may be backed by cache.
5. The controller adds pagination metadata and the current page content to the MVC `Model`.
6. The `vets/vetList` view is rendered.

### Resource/serialization flow

1. A client requests `GET /vets` with a JSON or XML accept header.
2. `VetController.showResourcesVetList()` loads all vets from the repository.
3. The controller wraps them in a `Vets` instance.
4. Spring serializes the wrapper object instead of a raw collection, which makes the output structure more predictable for marshalling.

### Vet specialty handling

`Vet` keeps specialties in a `Set` internally, but exposes them as a sorted list. That means:

- persistence and mutation use set semantics,
- outgoing serialized data is stable and ordered by specialty name,
- callers can ask how many specialties a vet has without inspecting the collection directly.

## Data Model

### Entities

- `Vet`
  - Table: `vets`
  - Inherits person fields from `Person`
  - Many-to-many association with `Specialty`
- `Specialty`
  - Table: `specialties`
  - Extends `NamedEntity`

### Association

- Join table: `vet_specialties`
- Join columns:
  - `vet_id`
  - `specialty_id`

The association is eager, so a vet's specialties are available immediately when the vet is loaded. This matches the read-mostly listing use case in this module and avoids extra lazy-loading work when the controller serializes or renders vets.

### Wrapper type

- `Vets`
  - Not a database entity
  - Used as a transport container for a list of vets in XML/JSON responses

## Dependencies and Integration

### Spring and framework dependencies

- Spring MVC for `@Controller`, `@GetMapping`, `Model`, and `@ResponseBody`
- Spring Data for `Page`, `Pageable`, and repository abstraction
- Spring Cache via `@Cacheable("vets")`
- Spring Transaction for read-only transaction boundaries
- JPA for entity mapping and many-to-many persistence
- JAXB annotations for serialization-friendly accessors

### Shared Petclinic model dependencies

- [`Person`](src/main/java/org/springframework/samples/petclinic/model/Person.java) is the base class for `Vet`
- [`NamedEntity`](src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java) is the base class for `Specialty` and is also used for sorting specialties by name

### Tests as usage examples

- [src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java)
- [src/test/java/org/springframework/samples/petclinic/vet/VetTests.java](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java)

These tests confirm the main behaviors: the controller renders the HTML view, exposes JSON resources, and the `Vet` entity is serializable.

## Mermaid Diagram

```mermaid
flowchart TD
VetController["VetController"] --> VetRepository["VetRepository"]
VetController --> Vets["Vets"]
VetRepository --> Vet["Vet"]
Vet["Vet"] --> Specialty["Specialty"]
Vets --> Vet
```

## Notes for Developers

- `VetController` uses a fixed page size of 5 for HTML listings. If you change the page size, update any UI assumptions and tests that rely on pagination behavior.
- `findPaginated()` converts from a 1-based request parameter to a 0-based `PageRequest`. Be careful when adding new pagination endpoints so you preserve that convention.
- The repository methods are cached under the `vets` cache name. If you change vet data mutations elsewhere in the application, consider whether that cache should be evicted or updated.
- `Vet.getSpecialties()` sorts output by specialty name. If callers depend on another ordering, that logic should be changed in one place only.
- The wrapper `Vets` type exists for serialization. If you are tempted to return a raw `List<Vet>`, check the downstream XML/JSON mapping requirements first.
- `Vet` lazily initializes its specialty set. That avoids null handling for callers and keeps entity construction simple in tests.

## Tests and Verification

- [VetControllerTests.showVetListHtml()](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java)
  - Verifies the HTML endpoint returns `vets/vetList` and populates `listVets`.
- [VetControllerTests.showResourcesVetList()](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java)
  - Verifies the resource endpoint returns JSON with the expected wrapper structure.
- [VetTests.serialization()](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java)
  - Verifies `Vet` survives Java serialization with its key fields intact.

These tests indicate that the package is meant to support both web rendering and object serialization, not just persistence.
