# Org / Springframework / Samples / Petclinic / Vet

## Overview

The `org.springframework.samples.petclinic.vet` package models veterinarians and their specialties, and exposes them through both HTML and JSON/XML-friendly controller endpoints. It appears to exist as the read-only “vets” slice of the Petclinic application: load vet data from persistence, present it in a paginated view, and support object serialization for web rendering and API-style responses.

This module is intentionally small, but it connects several concerns: JPA entities for the vet domain, a repository abstraction for retrieving vets, a controller for browser and resource requests, and JAXB-friendly wrapper types that make XML/JSON marshalling simpler.

## Key Classes and Interfaces

### `Vet`

[Source](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:43)

`Vet` is the primary domain entity in this package. It extends `Person`, so the inherited identity and name fields come from the shared model layer, while `Vet` adds a many-to-many relationship to `Specialty`.

Important details:

- It is mapped to the `vets` table with `@Entity` and `@Table(name = "vets")`.
- Its `specialties` collection is loaded eagerly.
- The relationship is persisted through the `vet_specialties` join table.
- It exposes a sorted, read-only style accessor for specialties while keeping the mutable internal set private.

Key methods:

- `getSpecialtiesInternal()` [Source](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:52)
  - Returns the backing `Set<Specialty>`.
  - Lazily initializes the set when needed.
  - This is the internal mutation path used by the other methods.
- `getSpecialties()` [Source](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:59)
  - Returns a `List<Specialty>` instead of a `Set`.
  - Sorts specialties by name using `NamedEntity::getName` before returning them.
  - Annotated with `@XmlElement`, so it is part of XML marshalled output.
- `getNrOfSpecialties()` [Source](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:66)
  - Returns the number of specialties associated with the vet.
- `addSpecialty(Specialty specialty)` [Source](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:70)
  - Adds one specialty to the backing set.
  - Used by tests and likely by data initialization code elsewhere in the application.

Why this design matters:

- The lazy initialization avoids null checks in callers.
- Returning a sorted list gives deterministic presentation order.
- Keeping the mutable collection internal reduces accidental external mutation of the entity state.

### `Specialty`

[Source](src/main/java/org/springframework/samples/petclinic/vet/Specialty.java:28)

`Specialty` models a veterinarian specialty such as dentistry or radiology. It extends `NamedEntity`, so it inherits the common identifier/name behavior used throughout Petclinic.

Important details:

- It is mapped to the `specialties` table.
- It has no additional fields beyond what `NamedEntity` provides.
- The class exists primarily to participate in the many-to-many relationship from `Vet`.

Why this design matters:

- Specialties are shared lookup-like records rather than embedded value objects.
- Keeping them as a dedicated entity allows multiple vets to reference the same specialty row.

### `VetRepository`

[Source](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java:38)

`VetRepository` is the repository abstraction used by the controller to read vet data. It extends Spring Data’s `Repository<Vet, Integer>` and declares only read methods, which makes the package clearly retrieval-oriented.

Important details:

- Both `findAll()` and `findAll(Pageable pageable)` are marked `@Transactional(readOnly = true)`.
- Both are cached with `@Cacheable("vets")`.
- The repository methods follow Spring Data naming conventions, so the implementation can be generated by Spring Data infrastructure.

Key methods:

- `findAll()` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java:44)
  - Returns all vets as a `Collection<Vet>`.
  - Intended for full-list resource responses.
- `findAll(Pageable pageable)` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java:54)
  - Returns a `Page<Vet>` for paginated UI rendering.
  - Lets the controller request one page at a time.

Why this design matters:

- The repository keeps persistence concerns out of the web layer.
- Caching helps avoid repeated database reads for the same vet listing.
- The overloaded `findAll` methods support both full and paginated use cases without duplicating query logic.

### `VetController`

[Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:35)

`VetController` handles HTTP requests for vet listings. It supports two representations of the same data: an HTML page for browser users and a marshalled `Vets` object for resource-oriented access.

Important details:

- `GET /vets.html` renders the HTML view `vets/vetList`.
- `GET /vets` returns a `Vets` wrapper directly as the response body.
- Pagination is fixed at five vets per page in the HTML flow.
- The controller constructs a `Vets` wrapper in both flows to make XML/JSON marshalling easier.

Key methods:

- Constructor `VetController(VetRepository vetRepository)` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:40)
  - Injects the repository dependency.
- `showVetList(@RequestParam(defaultValue = "1") int page, Model model)` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:44)
  - Handles the HTML listing endpoint.
  - Reads a `page` query parameter, defaulting to `1`.
  - Loads a page of vets, copies them into a `Vets` wrapper, and delegates model population to `addPaginationModel(...)`.
  - Returns the logical view name `vets/vetList`.
- `addPaginationModel(int page, Page<Vet> paginated, Model model)` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:54)
  - Adds pagination attributes to the model: `currentPage`, `totalPages`, `totalItems`, and `listVets`.
  - Returns the same view name used by the HTML flow.
- `findPaginated(int page)` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:63)
  - Converts the one-based page parameter into a zero-based `PageRequest`.
  - Requests a page of five vets from the repository.
- `showResourcesVetList()` [Source](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:69)
  - Handles the non-HTML endpoint `GET /vets`.
  - Builds a `Vets` wrapper containing all vets and returns it as `@ResponseBody`.

Why this design matters:

- The controller centralizes the formatting choice between HTML and resource response.
- Pagination is implemented in one place, so the UI stays consistent.
- Using `Vets` instead of a bare `List<Vet>` appears to simplify marshalling for XML and JSON serialization.

### `Vets`

[Source](src/main/java/org/springframework/samples/petclinic/vet/Vets.java:30)

`Vets` is a simple wrapper around a list of `Vet` objects. It exists mainly to support marshalling views, where a named root element is easier to serialize than a bare collection.

Important details:

- Annotated with `@XmlRootElement`, making it a JAXB root type.
- Exposes `getVetList()` with `@XmlElement`.
- Lazily initializes the list when accessed.

Key method:

- `getVetList()` [Source](src/main/java/org/springframework/samples/petclinic/vet/Vets.java:35)
  - Returns the backing `List<Vet>`.
  - Creates the list on first access.

Why this design matters:

- It provides a stable wrapper type for XML/JSON conversion.
- It avoids null collection handling in controller code.

### `package-info.java`

[Source](src/main/java/org/springframework/samples/petclinic/vet/package-info.java:16)

The package-info file in the evidence only shows the package declaration. No package-level annotations or additional documentation are present in the indexed content.

### Tests

#### `VetControllerTests`

[Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:43)

This test class verifies both controller entry points:

- `/vets.html?page=1` returns HTTP 200, populates the model, and resolves the `vets/vetList` view.
- `/vets` returns JSON with a `vetList` payload containing the expected vet ID.

Supporting methods:

- `james()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:54)
  - Creates a sample vet named James Carter.
- `helen()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:62)
  - Creates a sample vet named Helen Leary with a radiology specialty.
- `setup()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:74)
  - Stubs repository behavior for both paginated and non-paginated reads.
- `showVetListHtml()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:82)
  - Exercises the HTML listing endpoint.
- `showResourcesVetList()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:92)
  - Exercises the JSON resource endpoint.

#### `VetTests`

[Source](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java:26)

This test verifies that `Vet` is serializable. It serializes a sample vet and deserializes it back, then checks that first name, last name, and ID survive the round trip.

Key method:

- `serialization()` [Source](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java:28)
  - Confirms `Vet` can be safely stored and restored using Java serialization utilities.

## How It Works

### HTML vet listing flow

1. A browser requests `GET /vets.html?page=1`.
2. `VetController.showVetList(...)` reads the page number, defaults it to `1`, and converts it into a zero-based `PageRequest`.
3. `VetRepository.findAll(Pageable)` returns a page of vets, using the repository’s cached and read-only query path.
4. The controller populates the model with:
   - the current page number,
   - total page count,
   - total row count,
   - and the current page’s vets.
5. The controller returns the logical view name `vets/vetList`.

### Resource listing flow

1. A client requests `GET /vets`.
2. `VetController.showResourcesVetList()` loads all vets through `VetRepository.findAll()`.
3. The controller places them into a `Vets` wrapper.
4. Spring serializes the wrapper as the response body.

This appears to be optimized for simple marshalling rather than returning raw collections directly.

### Specialty handling inside `Vet`

- The specialties collection is stored as a `Set`, which prevents duplicates at the entity level.
- Callers interact with a sorted `List` from `getSpecialties()`, which is better for stable presentation and XML output.
- `addSpecialty(...)` mutates the internal set, while `getNrOfSpecialties()` provides a lightweight summary for UI display.

## Data Model

### Entity relationships

```mermaid
flowchart TD
    Vet["Vet"] --> Person["Person"]
    Vet --> Specialty["Specialty"]
    Vet --> VetSpecialties["vet_specialties join table"]
    Specialty --> NamedEntity["NamedEntity"]
    Vets["Vets wrapper"] --> Vet
```

### Model summary

- `Vet` inherits shared person fields from `Person` and adds a many-to-many specialty association.
- `Specialty` inherits the shared ID/name behavior from `NamedEntity` and serves as a reusable lookup entity.
- `Vets` is not a persistence entity; it is a transport wrapper for collection-based responses.

## Dependencies and Integration

This package depends on:

- `org.springframework.samples.petclinic.model` for shared base types like `Person` and `NamedEntity`
- Spring MVC for controller and model handling
- Spring Data for repository abstraction and pagination
- Spring Cache for cached vet lookups
- JAXB annotations for XML-friendly representation

Notable integration points:

- The controller talks only to `VetRepository`, keeping HTTP logic separate from persistence details.
- The repository methods are designed to be implemented by Spring Data infrastructure.
- The `Vets` wrapper is used to make the output easier for marshalling views and structured response bodies.

## Notes for Developers

- `Vet.getSpecialties()` returns a sorted list, not the raw set. If you need mutation, use `addSpecialty(...)` or internal entity management paths.
- `VetController` uses a fixed page size of 5. If you change that, update both the pagination logic and any UI assumptions.
- The HTML endpoint expects one-based page numbers from the request and converts them internally to zero-based indexing for `PageRequest`.
- Both repository methods are cached under the same cache name, `vets`. Be careful when changing query semantics, because stale cache entries could affect both paginated and non-paginated access.
- The tests intentionally cover both JSON resource output and HTML model/view behavior. If you change response shapes or view names, update the controller tests together with the implementation.

## At a Glance

- `Vet` is the core persistent entity for veterinarians.
- `Specialty` represents a vet specialty and participates in a many-to-many association.
- `VetRepository` supplies cached read access to vet data.
- `VetController` serves HTML and JSON-style vet listings.
- `Vets` is a JAXB-friendly wrapper used for collection responses.
