---
# (DD19) Business Logic — Owner.addVisit() [11 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `org.springframework.samples.petclinic.owner.Owner` |
| Layer | Domain Model |
| Module | `owner` (Package: `org.springframework.samples.petclinic.owner`) |

## 1. Role

### Owner.addVisit()

This method attaches a newly prepared `Visit` object to a specific `Pet` owned by the current `Owner`. In business terms, it is the domain-level operation that records a visit against an existing pet record, ensuring that the visit is associated with the correct pet before the owner aggregate is persisted. The method acts as a guard-railed routing step: it validates the incoming identifiers, resolves the target pet from the owner’s pet collection, and then delegates the actual association to `Pet.addVisit(visit)`.

The method handles a single business category: pet visit registration. It does not branch into multiple service types, but it does enforce three sequential validations/steps: `petId` must exist, `visit` must exist, and the requested pet must be found under the owner. If any of those conditions fail, the method stops through assertion failure rather than silently continuing. As a design pattern, it follows delegation and aggregate-boundary enforcement: `Owner` owns the lookup responsibility, while `Pet` owns the visit collection mutation.

Within the larger PetClinic flow, this method is a supporting domain operation used by the visit creation screen before the owner aggregate is saved. It is not a controller entry point itself; rather, it is a reusable domain helper that preserves the integrity of the owner-pet relationship while keeping the web layer thin. The method therefore plays the role of a transaction-safe domain mutator inside the owner aggregate.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["addVisit(petId, visit)"]
    A["Assert petId is not null"]
    B["Assert visit is not null"]
    C["Call getPet(petId)"]
    D{"pet found?"}
    E["Assert pet is not null"]
    F["Call pet.addVisit(visit)"]
    END_NODE["Return / Next"]

    START --> A
    A --> B
    B --> C
    C --> D
    D -->|yes| E
    D -->|no| E
    E --> F
    F --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `petId` | `Integer` | The business identifier of the pet that should receive the new visit record. It must point to a pet owned by the current owner; otherwise the method rejects the request. |
| 2 | `visit` | `Visit` | The visit domain object to be attached to the pet. It represents the appointment/clinical visit details that will be stored under the pet’s visit history. |

**Instance fields / external state read by the method**
- `Owner`’s internal pet collection through `getPet(petId)`.
- `Pet` aggregate state indirectly, because the method delegates the append operation to the resolved pet.

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `Owner.getPet` | Owner | `Pet` collection in `Owner` aggregate | Locates the pet owned by this owner using the supplied identifier |

Analyze all method calls within this method and classify each as a CRUD operation.
Use the pre-computed evidence above. If SC Code or Entity/DB is missing, try to infer from:
- The **SC Code** (Service Component code, e.g., `EKK0361A010SC`, `EKK1081D010CBS`) — look at the class name of the called method or its containing class.
- The **Entity/DB tables** — search for table name constants (often `KK_T_*` pattern), SQL references, or entity names in the called method’s source code.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `Owner.getPet` | Owner | `Pet` collection in `Owner` aggregate | Reads the owner’s pet collection to resolve the requested pet by identifier |
| C | `Pet.addVisit` | Pet | `Visit` collection in `Pet` aggregate | Creates the association between the pet and the new visit by appending it to the pet’s visit list |

## 5. Dependency Trace

Trace who calls this method and what this method ultimately calls.
Use the pre-computed evidence and caller search results from Step 2 above.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Controller: `VisitController` | `VisitController.processNewVisitForm()` -> `Owner.addVisit()` | `Pet.addVisit [C] Visit collection` |
| 2 | Test: `ClinicServiceTests` | `ClinicServiceTests` -> `Owner.addVisit()` | `Pet.addVisit [C] Visit collection` |

**Notes**
- The web flow invokes this method from `VisitController.processNewVisitForm(...)` after binding and validation.
- The method’s terminal business effect is the append of a `Visit` into the target pet’s visit collection; persistence is handled later by the caller when the owner aggregate is saved.

## 6. Per-Branch Detail Blocks

**Block 1** — **EXEC** `(assert petId is not null)` (L166)

> Business guard that prevents visit registration from continuing without a target pet identifier.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `Assert.notNull(petId, "Pet identifier must not be null!");` |

**Block 2** — **EXEC** `(assert visit is not null)` (L167)

> Business guard that ensures the visit payload exists before the method attempts to attach it to a pet.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `Assert.notNull(visit, "Visit must not be null!");` |

**Block 3** — **CALL** `(resolve pet by identifier)` (L169)

> Looks up the target pet inside the owner aggregate.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `Pet pet = getPet(petId);` |

**Block 4** — **EXEC** `(assert pet is not null)` (L171)

> Prevents the method from attaching a visit to a missing or unauthorized pet reference.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `Assert.notNull(pet, "Invalid Pet identifier!");` |

**Block 5** — **CALL** `(append visit to pet)` (L173)

> Delegates the actual collection mutation to the pet aggregate.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `pet.addVisit(visit);` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Pet owner aggregate root that holds the owner’s pets and related domain behavior |
| `Pet` | Domain entity | Animal owned by an owner; receives visit records |
| `Visit` | Domain entity | Clinical or appointment visit record associated with a pet |
| `petId` | Field | Identifier of the target pet within the owner’s pet list |
| `getPet` | Method | Owner lookup method used to resolve a pet by identifier |
| `addVisit` | Method | Domain operation that appends a visit to a pet’s visit history |
| `Assert.notNull` | Validation utility | Spring validation guard that stops processing when a required business value is missing |
| Aggregate | Domain concept | A consistency boundary where the owner and its pets are managed together |
| CRUD | Technical term | Create, Read, Update, Delete operation classification used to describe data access or mutation |
| Controller | Layer | Web endpoint handler that collects form data and invokes domain logic |
| VisitController | Controller | Spring MVC controller that submits new pet visits |
| PetClinic | Application domain | Sample veterinary clinic system used to manage owners, pets, and visits |
| BindingResult | Technical term | Spring MVC validation result holder used before domain mutation |
| `processNewVisitForm` | Method | Web flow step that validates and submits the new visit |
| `save` | Method | Persistence operation invoked by the controller after the visit is added |
| owner aggregate | Domain concept | The owner object plus its owned pets, treated as a single consistency unit |
| visit history | Business term | The ordered collection of visit records recorded for a pet |
| identifier | Business term | Unique value used to select a specific pet record |
