# Org / Springframework / Samples / Petclinic / Vet

## Overview

The `org.springframework.samples.petclinic.vet` module appears to own the veterinarian-facing part of Petclinic: the `Vet` domain model, its specialization data, and the web endpoints that expose veterinarians to both HTML and JSON/XML clients. It also provides the repository contract used by the controller to read vet data from the persistence layer.

This module exists to support the common Petclinic use case of listing veterinarians and their specialties in the UI and in machine-readable formats. The code is intentionally small, but it bridges several concerns: JPA entity mapping, pagination, caching, and XML/JSON-friendly wrapper objects.

## Key Classes and Interfaces

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

`Specialty` models a veterinarian specialty such as dentistry or radiology. It is a very thin JPA entity that inherits its identifier and name behavior from `NamedEntity`, so this class mainly exists to give the domain a dedicated type and a dedicated table mapping.

Key points:
- Annotated with `@Entity` and mapped to the `specialties` table.
- Extends `NamedEntity`, which provides the common `id` and `name` fields used across the Petclinic model.
- Contains no additional fields or methods, which suggests specialties are treated as simple reference data.

Because `Specialty` is so small, most of its behavior comes from the shared base class and JPA annotations rather than from custom logic in the class itself.

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

`Vet` is the central domain type in this module. It represents a veterinarian and extends `Person`, which means it inherits name and identity fields from the shared Petclinic person model. The class also owns the relationship to `Specialty` through a many-to-many association.

Important design details:
- `@Entity` mapped to the `vets` table.
- Inherits from `Person`, so it participates in the broader person/identity model used elsewhere in the application.
- Declares `specialties` as an eager `@ManyToMany` relationship through the `vet_specialties` join table.
- Uses JAXB annotations on `getSpecialties()` so the vet can be serialized cleanly when returned through XML-oriented endpoints.

Key methods:
- [Vet.getSpecialtiesInternal()](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:52) returns the backing `Set<Specialty>`. It lazily initializes the set to a `HashSet` if needed, which avoids null checks in the rest of the class.
- [Vet.getSpecialties()](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:59) returns a `List<Specialty>` sorted by specialty name. This is the public accessor used for serialization and presentation, so callers see a stable order.
- [Vet.getNrOfSpecialties()](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:66) returns the number of specialties currently associated with the vet.
- [Vet.addSpecialty(Specialty specialty)](src/main/java/org/springframework/samples/petclinic/vet/Vet.java:70) adds a specialty to the backing set.

The class uses a `Set` internally but exposes a sorted `List` externally. That combination is useful because it preserves uniqueness in memory while producing deterministic output for the UI and for serialization.

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

`VetRepository` defines the read-side data access contract for veterinarians. It is a Spring Data `Repository` interface rather than a concrete implementation, so Spring can generate the actual repository implementation at runtime from the method signatures.

Key characteristics:
- Extends `Repository<Vet, Integer>`, indicating `Vet` is the aggregate type and `Integer` is the identifier type.
- Declares only query methods, not mutating operations.
- Marks both methods as read-only transactions and cacheable with the `vets` cache.

Key methods:
- [VetRepository.findAll()](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java:44) returns all vets as a `Collection<Vet>`. The Javadoc says it retrieves all vets from the data store, and the method is read-only and cacheable.
- [VetRepository.findAll(Pageable pageable)](src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java:54) returns a `Page<Vet>` for paginated access. The controller uses this for the HTML view.

The repository is deliberately minimal. Its role is to express the persistence contract and let Spring Data handle the implementation details.

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

`VetController` is the web layer entry point for veterinarian listings. It exposes two GET endpoints: one that renders the HTML page and one that returns the raw resource representation.

Routes and behavior:
- `GET /vets.html` returns the `vets/vetList` view and populates the model with pagination data and the current page of vets.
- `GET /vets` returns a `Vets` wrapper object directly as the response body, which is useful for JSON/XML marshalling.

Key methods:
- [VetController.VetController(VetRepository vetRepository)](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:40) injects the repository dependency.
- [VetController.showVetList(@RequestParam(defaultValue = "1") int page, Model model)](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:44) handles the HTML list page. It creates a `Vets` wrapper, loads a page of vets, and delegates to the pagination model helper.
- [VetController.addPaginationModel(int page, Page<Vet> paginated, Model model)](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:54) adds `currentPage`, `totalPages`, `totalItems`, and `listVets` to the model, then returns the view name `vets/vetList`.
- [VetController.findPaginated(int page)](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:63) creates a `PageRequest` with a fixed page size of 5 and asks the repository for that page.
- [VetController.showResourcesVetList()](src/main/java/org/springframework/samples/petclinic/vet/VetController.java:69) loads all vets and returns them wrapped in `Vets` for object serialization.

The controller comments explain why it returns a wrapper type rather than a bare collection: it simplifies XML and JSON mapping. That is a common pattern in Spring MVC applications where collection roots need stable serialization shapes.

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

`Vets` is a small JAXB-friendly wrapper around a `List<Vet>`. It exists primarily to support marshalling views and response-body serialization where a collection wrapper is easier to consume than a raw list.

Key points:
- Annotated with `@XmlRootElement`, making it suitable as a serialization root.
- Lazily initializes its internal list.
- Exposes the list through [Vets.getVetList()](src/main/java/org/springframework/samples/petclinic/vet/Vets.java:35), which returns a mutable `List<Vet>` and creates the list on first access.

This class does not add business logic; it mainly standardizes the response shape for vet collections.

## How It Works

A typical HTML request flows through the module like this:

1. A client requests `GET /vets.html?page=1`.
2. `VetController.showVetList()` creates a `Vets` wrapper and asks `findPaginated(1)` for a page of results.
3. `findPaginated()` converts the 1-based page number into a zero-based `PageRequest` with a fixed page size of 5.
4. `VetRepository.findAll(Pageable)` returns a `Page<Vet>`.
5. `addPaginationModel()` copies the page metadata into the MVC `Model` and returns the view name `vets/vetList`.
6. The view renders the current page, total page count, and total item count.

A resource-style request follows a simpler path:

1. A client requests `GET /vets` with a JSON or XML `Accept` header.
2. `VetController.showResourcesVetList()` loads all vets from the repository.
3. The method wraps the results in a `Vets` instance and returns it as `@ResponseBody`.
4. Spring’s message conversion infrastructure serializes the wrapper into JSON or XML.

The `Vet` entity itself is designed to support both of those flows. It keeps specialties in a `Set` for uniqueness, but the public getter sorts them by name before exposure. That means views and serialized payloads are deterministic, which is important for tests and for user-facing ordering.

## Data Model

The vet module centers on two entity types:

- `Vet` - a person record representing a veterinarian.
- `Specialty` - a reference entity representing a vet specialty.

Relationships and mapping:
- `Vet` extends `Person`, so it inherits the shared person fields from the common model.
- `Specialty` extends `NamedEntity`, so it inherits identifier and name behavior.
- `Vet.specialties` is a many-to-many relationship mapped through the `vet_specialties` join table.
- The association uses eager fetching, so specialty data is loaded with the vet.

Wrapper types:
- `Vets` is not a persistence entity. It is a transport wrapper used to expose a list of vets cleanly in XML/JSON-oriented responses.

The test data in `VetControllerTests` shows the expected shape of this model: one vet can have zero specialties, while another can have one or more specialties attached.

## Dependencies and Integration

This module depends on the shared Petclinic model and Spring infrastructure:

- `org.springframework.samples.petclinic.model.Person` and `NamedEntity` provide the base fields used by `Vet` and `Specialty`.
- Spring Data repository support provides the generated implementation behind `VetRepository`.
- Spring MVC provides the controller and model handling in `VetController`.
- Spring’s cache abstraction is used via `@Cacheable("vets")` on repository methods.
- JAXB annotations (`@XmlRootElement`, `@XmlElement`) shape XML serialization for the wrapper and vet specialties.

The main relationship between the classes is shown below:

```mermaid
flowchart LR
  VetController["VetController"] --> VetRepository["VetRepository"]
  VetController --> Vets["Vets"]
  VetRepository --> Vet["Vet"]
  Vet --> Specialty["Specialty"]
  Vet --> Person["Person"]
  Specialty --> NamedEntity["NamedEntity"]
  Vets --> Vet
```

## Tests and Expected Behavior

The tests document the intended behavior of the module:

- [VetTests.serialization()](src/test/java/org/springframework/samples/petclinic/vet/VetTests.java:28) verifies that a `Vet` can be serialized and deserialized while preserving first name, last name, and id. This confirms the entity is safe to use with serialization-based infrastructure.
- [VetControllerTests.showVetListHtml()](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:82) verifies that `/vets.html?page=1` returns HTTP 200, populates the `listVets` model attribute, and resolves to the `vets/vetList` view.
- [VetControllerTests.showResourcesVetList()](src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java:92) verifies that `/vets` returns JSON and that the wrapped vet list contains the expected data.

The test setup also shows the controller’s assumptions:
- The repository is expected to support both unpaged and paged reads.
- The response shape for `/vets` is a wrapper object with a `vetList` property.
- Specialties are attached directly to a vet in memory and then exposed through the getter.

## Notes for Developers

- `Vet.getSpecialties()` sorts by specialty name each time it is called. If you add specialties with null names or want a different order, this method is the place to review.
- `VetController` hardcodes a page size of 5. If you need different pagination behavior, adjust `findPaginated()` and the corresponding view expectations together.
- The controller uses a wrapper object for both HTML and JSON/XML paths. If you replace it with a raw collection, you will likely need to update serialization and tests.
- `VetRepository` is cacheable. If you introduce writes or administrative vet management later, make sure you understand cache invalidation requirements.
- `Vets` and `Specialty` are intentionally minimal transport/entity types. Their purpose is to support serialization and persistence, not to hold business rules.
- The comments in `VetController` suggest the wrapper type exists to simplify object-XML and object-JSON mapping. That pattern is important if you extend the module with additional endpoints.
