# Org / Springframework / Samples / Petclinic / Owner/other

## Overview

This package groups the owner-facing domain model and supporting Spring MVC infrastructure for Petclinic. It appears to be the part of the application that manages owners, their pets, pet types, and pet visits, along with the formatting and validation needed to bind web forms correctly.

The module is intentionally small but central: the domain objects model the relationship between owners, pets, and visits, while the formatter and validator make the web layer work smoothly with Spring MVC form binding and error handling. The test classes show the expected request flows through the owner, pet, and visit controllers.

## Key Classes and Interfaces

### [Owner](src/main/java/org/springframework/samples/petclinic/owner/Owner.java:47)

`Owner` is the aggregate root for the owner subdomain. It extends `Person` and maps to the `owners` table, storing the owner's contact information and an eager list of pets.

Important responsibilities:
- Holds address, city, and telephone data with bean validation constraints.
- Owns the `pets` collection through a JPA one-to-many association.
- Provides lookup helpers for finding a pet by name or id.
- Centralizes visit addition through `addVisit(Integer petId, Visit visit)`.

Key methods:
- `getAddress()`, `setAddress(String)` — accessors for the owner's address.
- `getCity()`, `setCity(String)` — accessors for the owner's city.
- `getTelephone()`, `setTelephone(String)` — accessors for the telephone number.
- `getPets()` — returns the mutable in-memory list of pets.
- `addPet(Pet pet)` — adds only new pets, so existing persistent pets are not duplicated in the collection.
- `getPet(String name)` and `getPet(String name, boolean ignoreNew)` — case-insensitive lookup by pet name, with optional exclusion of unsaved pets.
- `getPet(Integer id)` — lookup by pet id, skipping unsaved pets.
- `addVisit(Integer petId, Visit visit)` — validates inputs, resolves the pet, and delegates the visit addition to that pet.
- `toString()` — renders a diagnostic summary via `ToStringCreator`.

The `Owner` class is the main coordination point for pet and visit operations. The controller tests show it being used as the root object for owner detail pages, edit flows, and nested pet/visit creation.

### [Pet](src/main/java/org/springframework/samples/petclinic/owner/Pet.java:44)

`Pet` models an animal owned by an `Owner`. It extends `NamedEntity`, maps to the `pets` table, and stores a birth date, a pet type, and a set of visits.

Important responsibilities:
- Stores the pet's date of birth in a form-friendly `LocalDate` field.
- Links to a `PetType` through a many-to-one association.
- Holds visit history in insertion order through a `LinkedHashSet`.

Key methods:
- `setBirthDate(LocalDate)` / `getBirthDate()` — accessors for the pet's birth date.
- `getType()` / `setType(PetType)` — accessors for the pet type.
- `getVisits()` — returns the visit collection.
- `addVisit(Visit visit)` — appends a visit to the set.

`Pet` is deliberately lightweight. It depends on `PetType` for classification and `Visit` for history, while validation rules for user input are handled separately by `PetValidator`.

### [PetType](src/main/java/org/springframework/samples/petclinic/owner/PetType.java:26)

`PetType` is a simple lookup entity for the kind of animal being registered, such as dog or cat. It extends `NamedEntity` and maps to the `types` table.

This class contains no custom behavior of its own; its purpose is to provide a persistent reference value that can be selected from forms and rendered by `PetTypeFormatter`.

### [PetTypeFormatter](src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java:36)

`PetTypeFormatter` integrates pet types with Spring MVC data binding. It is a Spring component that teaches the framework how to convert between the textual form value and the corresponding `PetType` entity.

Important responsibilities:
- Prints a `PetType` as its name for display in views.
- Parses a submitted string back into the matching `PetType` by consulting the repository.

Key methods:
- `PetTypeFormatter(PetTypeRepository types)` — constructor injection of the repository used for lookups.
- `print(PetType petType, Locale locale)` — returns the pet type name, or `"<null>"` if the name is missing.
- `parse(String text, Locale locale)` — loads all pet types via `findPetTypes()`, matches by exact name, and throws `ParseException` if no match is found.

This formatter is essential for the pet create and edit forms. The tests show that the MVC layer expects a string like `hamster` to bind to the correct `PetType` instance.

### [PetValidator](src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java:32)

`PetValidator` contains form validation rules for `Pet` objects. It implements Spring's `Validator` interface rather than relying only on bean validation annotations, because the rules are simpler to express directly in code.

Important responsibilities:
- Rejects missing pet names.
- Rejects missing pet types when creating a new pet.
- Rejects missing birth dates.

Key methods:
- `validate(Object obj, Errors errors)` — casts the input to `Pet` and adds field errors when required values are absent. It uses the shared error code `required`.
- `supports(Class<?> clazz)` — returns `true` only for `Pet` subclasses.

The validator distinguishes between new and existing pets for type validation: `type` is required only when `pet.isNew()` is true. That matches the controller tests, which check for `required` errors on creation while allowing updates to proceed differently.

### [Visit](src/main/java/org/springframework/samples/petclinic/owner/Visit.java:34)

`Visit` represents a single appointment or checkup for a pet. It maps to the `visits` table and extends `BaseEntity`.

Important responsibilities:
- Stores the visit date.
- Stores a textual description of the visit.
- Initializes the date to the current day by default.

Key methods:
- `Visit()` — sets the date to `LocalDate.now()` so a newly created visit is immediately date-stamped.
- `getDate()` / `setDate(LocalDate)` — accessors for the visit date.
- `getDescription()` / `setDescription(String)` — accessors for the visit description.

Because the constructor pre-populates the date, visit forms only need to supply the description in the common case. The controller tests confirm that a visit can be created and then attached to a pet through the owner aggregate.

## How It Works

The package centers on a simple aggregate flow:

1. An owner is loaded from the repository.
2. The owner exposes its pets through an eager collection.
3. A pet is created or edited with a type and birth date.
4. Visits are added to a specific pet under an owner.
5. Spring MVC uses the formatter and validator to bind and check form submissions.

### Typical owner flow

The owner controller tests show the owner lifecycle:
- `GET /owners/new` renders an owner creation form.
- `POST /owners/new` creates a new owner when the required fields are present.
- `GET /owners/find` shows the search form.
- `GET /owners?page=1` searches by last name and either lists matches or redirects directly to a single owner.
- `GET /owners/{ownerId}` renders owner details, including pets and their visits.
- `GET` and `POST /owners/{ownerId}/edit` support editing and validate that the path id matches the submitted owner.

### Typical pet flow

The pet controller tests show how pets are managed under an owner:
- `GET /owners/{ownerId}/pets/new` prepares an empty `Pet` form.
- `POST /owners/{ownerId}/pets/new` validates the pet and creates it when data is valid.
- `GET /owners/{ownerId}/pets/{petId}/edit` loads an existing pet for editing.
- `POST /owners/{ownerId}/pets/{petId}/edit` updates an existing pet.

During those flows, `PetValidator` enforces required data and `PetTypeFormatter` converts the submitted type field into a `PetType` entity.

### Typical visit flow

The visit controller tests show the visit lifecycle:
- `GET /owners/{ownerId}/pets/{petId}/visits/new` renders the new-visit form.
- `POST /owners/{ownerId}/pets/{petId}/visits/new` creates a `Visit` when the description is present.
- The visit is then attached to the resolved pet through the owner aggregate.

### Mermaid relationship diagram

```mermaid
flowchart TD
OwnerModule["Owner package"] --> Owner["Owner"]
OwnerModule --> Pet["Pet"]
OwnerModule --> PetType["PetType"]
OwnerModule --> PetTypeFormatter["PetTypeFormatter"]
OwnerModule --> PetValidator["PetValidator"]
OwnerModule --> Visit["Visit"]
Owner --> Pet
Pet --> PetType
Pet --> Visit
PetTypeFormatter --> PetType
PetValidator --> Pet
```

## Data Model

The model is straightforward and centered around ownership:

- `Owner` stores personal and contact information.
- `Owner` owns many `Pet` objects.
- `Pet` belongs to one `PetType`.
- `Pet` owns many `Visit` objects.

Notable persistence choices:
- `Owner.pets` is eager, ordered by pet name, and cascades all persistence operations.
- `Pet.visits` is eager, ordered by visit date ascending, and cascades all persistence operations.
- `Owner` and `Pet` use helper methods that preserve aggregate integrity when adding nested children.

Because the collection fields are initialized eagerly in memory, the aggregate is easy to work with in controller code and test fixtures.

## Dependencies and Integration

This module integrates with the rest of the application through a few Spring and JPA contracts:

- `Owner`, `Pet`, `PetType`, and `Visit` are JPA entities.
- `PetTypeFormatter` is a Spring MVC `Formatter` that depends on `PetTypeRepository`.
- `PetValidator` is a Spring `Validator` used by form handling logic.
- `Owner` uses `Person` as its superclass.
- `Pet`, `PetType`, and `Visit` use the shared `NamedEntity` and `BaseEntity` abstractions from the model package.

The test classes confirm that the package is wired into MVC controllers rather than operating as a standalone domain model.

## Notes for Developers

- `Owner.addPet(Pet)` only adds pets that are still new. If you reuse the same `Pet` instance or try to reattach an existing pet, this method will not duplicate it.
- `Owner.getPet(String, boolean)` performs a case-insensitive name match and can optionally skip unsaved pets. This matters when validating duplicate names in create flows.
- `Owner.getPet(Integer)` ignores new pets because they do not yet have stable ids.
- `Owner.addVisit(Integer, Visit)` fails fast with `Assert.notNull` if either argument is missing or if the pet id does not resolve.
- `PetValidator` uses plain error code strings such as `required`, which the view layer can map to localized messages.
- `PetValidator` only requires `type` for new pets. Existing pets can be updated without re-selecting the type unless the controller imposes additional rules.
- `PetTypeFormatter.parse(...)` searches by exact name, so repository values and form submissions must agree on the stored pet type name.
- `Visit` sets its date automatically in the constructor, which simplifies new-visit form initialization.

## Test Coverage Signals

The tests in this package show the intended behavior of the module:

- [OwnerControllerTests](src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java:58) covers owner creation, search, update, detail display, and id mismatch handling.
- [PetControllerTests](src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java:48) covers pet creation, duplicate-name handling, missing type handling, and invalid birth dates.
- [PetTypeFormatterTests](src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java:41) verifies string-to-entity and entity-to-string conversion.
- [PetValidatorTests](src/test/java/org/springframework/samples/petclinic/owner/PetValidatorTests.java:39) verifies required-field validation.
- [VisitControllerTests](src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java:43) covers visit form rendering and submission.

These tests are a good reference when extending the package, because they encode the expected MVC behavior and validation rules.
