---
# (DD18) Business Logic — Owner.getPet() [11 LOC]

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

## 1. Role

### Owner.getPet()

This method performs owner-scoped pet lookup inside the Petclinic domain model. It searches the pets already associated with a specific `Owner` and returns the first `Pet` whose name matches the requested value, using case-insensitive comparison. The second parameter adds a business rule for create flows: when `ignoreNew` is `true`, the method suppresses unsaved pets so validation logic can check for duplicates only among persisted pets. When `ignoreNew` is `false`, the method includes both persisted and newly created pets, which supports general retrieval and update scenarios. The method therefore acts as a shared in-memory selector used by controller flows that need to find a pet by identity-like business attributes without querying the database directly. Its control flow is simple but important: iterate through the owner’s pets, compare names, optionally exclude new pets, and return the matching pet or `null` if none qualifies.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["getPet(name, ignoreNew)"])
    LOOP(["For each Pet in getPets()"])
    GET_NAME(["Read pet.getName()"])
    NAME_CHECK{"compName != null and equalsIgnoreCase(name)?"}
    IGNORE_CHECK{"ignoreNew = true and pet.isNew()?"}
    RETURN_PET(["Return matching Pet"])
    CONTINUE_LOOP(["Continue to next Pet"])
    END_NODE(["Return null"])

    START --> LOOP
    LOOP --> GET_NAME
    GET_NAME --> NAME_CHECK
    NAME_CHECK -- "No" --> CONTINUE_LOOP
    NAME_CHECK -- "Yes" --> IGNORE_CHECK
    IGNORE_CHECK -- "No" --> RETURN_PET
    IGNORE_CHECK -- "Yes" --> CONTINUE_LOOP
    CONTINUE_LOOP --> LOOP
    LOOP --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `name` | `String` | Pet business name used to locate a specific pet belonging to the owner. The comparison is case-insensitive, so `Max` and `max` are treated as the same business identifier. |
| 2 | `ignoreNew` | `boolean` | Duplicate-check and lookup control flag. When `true`, the method excludes unsaved pets from matching so creation flows do not treat the current transient pet as an existing duplicate; when `false`, all owner pets are eligible. |

**External state read by the method:** the owner’s `pets` collection via `getPets()`, and each candidate pet’s `name` and `isNew()` state.

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `Owner.getPets` | Owner | - | Calls `getPets` in `Owner` |

Analyze all method calls within this method and classify each as a CRUD operation.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `getPets()` | Owner | `Pet` collection on `Owner` | Reads the owner’s associated pets to evaluate candidates for a name match. |
| R | `pet.getName()` | Pet | `Pet` | Reads the pet name for case-insensitive comparison against the requested business name. |
| R | `pet.isNew()` | Pet | `Pet` | Reads transient/persisted state to exclude unsaved pets when `ignoreNew` is enabled. |

## 5. Dependency Trace

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

No screen/batch entry points found within 8 hops. Direct callers found: 2 methods.
Terminal operations from this method: `getPets` [R]

Trace who calls this method and what this method ultimately calls.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Controller: `OwnerController` | `OwnerController.processCreationForm` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |
| 2 | Controller: `OwnerController` | `OwnerController.processUpdateForm` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |
| 3 | Controller: `PetController` | `PetController.processCreationForm` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |
| 4 | Controller: `PetController` | `PetController.processUpdateForm` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |
| 5 | Controller: `PetController` | `PetController.updatePetDetails` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |
| 6 | Controller: `VisitController` | `VisitController.loadPetWithVisit` -> `Owner.getPet(Integer)` -> `Owner.getPet(String, boolean)` | `getPets [R] Pet collection` |

## 6. Per-Branch Detail Blocks

**Block 1** — **FOR** `(for each pet in getPets())` (L136)

> Iterates over every pet owned by the current owner and evaluates it as a candidate match.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getPets();` // read the owner’s pet collection |
| 2 | SET | `for (Pet pet : getPets())` // begin iteration over associated pets |

**Block 1.1** — **SET / READ** `(inside loop)` (L137)

> Reads the current candidate pet name for comparison.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String compName = pet.getName();` // cache the pet name for comparison |
| 2 | CALL | `pet.getName();` // read the pet’s business name |

**Block 1.2** — **IF** `(compName != null && compName.equalsIgnoreCase(name))` (L138)

> Matches pets by name without case sensitivity.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (compName != null && compName.equalsIgnoreCase(name))` // evaluate business-name equality |

**Block 1.2.1** — **IF** `(!ignoreNew || !pet.isNew())` (L139)

> Applies the transient-pet filter only when the caller asks to ignore new pets.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (!ignoreNew || !pet.isNew())` // allow persisted pets, or all pets when ignoreNew is false |
| 2 | CALL | `pet.isNew();` // check whether the pet has been persisted |
| 3 | RETURN | `return pet;` // return the first qualifying match |

**Block 1.2.2** — **END IF** `(name matched but pet is new and ignoreNew is true)` (L139)

> Skips unsaved pets during duplicate validation and continues scanning the remaining pets.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue` implicit via loop progression // no return because the pet is excluded |

**Block 1.3** — **END IF** `(name does not match)` (L138)

> Continues to the next candidate when the pet name is different or missing.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue` implicit via loop progression // move to the next pet |

**Block 2** — **RETURN** `(no matching pet found)` (L143)

> Returns `null` when the owner has no pet satisfying both the name match and the `ignoreNew` rule.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return null;` // no eligible pet was found |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain object | Pet owner record that groups one or more pets under the same person. |
| `Pet` | Domain object | Animal record owned by an owner; can be new (unsaved) or persisted. |
| `getPets()` | Method | Returns the owner’s associated pet collection for in-memory traversal. |
| `isNew()` | Method | Indicates whether a domain object has not been persisted yet. |
| `ignoreNew` | Business flag | Lookup control used to skip transient pets during duplicate checks. |
| Case-insensitive match | Business rule | Treats pet names as equal regardless of upper/lower case differences. |
| Transient / new pet | Domain state | A pet object that exists in the form or model but has not been saved yet. |
| Persisted pet | Domain state | A pet that already exists in the underlying data store. |
| `OwnerController` | Controller | MVC handler for owner creation, update, and display flows. |
| `PetController` | Controller | MVC handler for pet creation and update flows. |
| `VisitController` | Controller | MVC handler for visit booking flows that first resolves the pet on an owner. |
