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

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

## 1. Role

### Owner.getPet()

This method performs an in-memory lookup of a pet that belongs to the current `Owner` aggregate. It walks the owner’s associated pet collection, compares each pet name against the requested business name, and returns the first matching pet instance when the match is eligible for selection. The method supports two business modes: a normal lookup that can return either persisted or newly created pets, and a filtered lookup that excludes pets that have not been saved yet. In effect, it acts as a small routing and validation gate for pet selection logic used by owner-facing screens and controllers.

The method implements a simple linear search and conditional dispatch pattern over the owner’s pet list. Its role in the larger system is to provide a reusable domain-level finder so callers do not need to duplicate pet-name matching rules or new-pet filtering behavior. If no pet matches the supplied name, or if all matching pets are excluded by the `ignoreNew` flag, the method returns `null` to indicate that the owner has no eligible pet with that name.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
START["getPet(name, ignoreNew)"]
LOOP["Iterate over getPets()"]
GET_NAME["Read pet.getName() into compName"]
COND_NAME{ "compName != null and equalsIgnoreCase(name)" }
COND_IGNORE{ "!ignoreNew or !pet.isNew()" }
RETURN_PET["Return matching Pet"]
RETURN_NULL["Return null"]
START --> LOOP
LOOP --> GET_NAME
GET_NAME --> COND_NAME
COND_NAME -->|No| LOOP
COND_NAME -->|Yes| COND_IGNORE
COND_IGNORE -->|Yes| RETURN_PET
COND_IGNORE -->|No| LOOP
LOOP --> RETURN_NULL
```

**CRITICAL — Constant Resolution:**
This method does not reference any constants. No constant-driven branching is present in the source.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `name` | `String` | Business pet name used to identify an owner’s pet by display name or registration name. The method accepts any case variation because the comparison is case-insensitive. |
| 2 | `ignoreNew` | `boolean` | Selection rule for newly created pets. When `true`, the method excludes pets that have not been saved yet; when `false`, new pets are eligible for matching. |

**External state read by the method:**
- `getPets()` from the current `Owner` instance
- Each candidate `Pet`’s `name`
- Each candidate `Pet`’s `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.
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.getPets` | Owner | Owner.pets collection | Reads the owner’s associated pet collection for in-memory filtering. |
| R | `Pet.getName` | Pet | Pet.name field | Reads the candidate pet name for case-insensitive matching. |
| R | `Pet.isNew` | Pet | Pet.new state | Reads persistence state to exclude unsaved pets when requested. |

## 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.
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 | Screen: `PetController` | `PetController` -> `Owner.getPet(String, boolean)` | `getPets [R] Owner.pets collection` |
| 2 | Screen: `VisitController` | `VisitController` -> `Owner.getPet(String, boolean)` | `getPets [R] Owner.pets collection` |
| 3 | Test: `OwnerControllerTests` | `OwnerControllerTests` -> `Owner.getPet(String)` -> `Owner.getPet(String, boolean)` | `getPets [R] Owner.pets collection` |
| 4 | Test: `ClinicServiceTests` | `ClinicServiceTests` -> `Owner.getPet(String)` -> `Owner.getPet(String, boolean)` | `getPets [R] Owner.pets collection` |

## 6. Per-Branch Detail Blocks

**Block 1** — [FOR] `(for (Pet pet : getPets()))` (L136)

> Iterates through every pet currently attached to the owner and evaluates each candidate against the requested name.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getPets();` // obtain the owner’s pet collection |
| 2 | EXEC | `for (Pet pet : getPets()) { ... }` // evaluate each pet in order |

**Block 1.1** — [SET] `(String compName = pet.getName())` (L137)

> Captures the current candidate’s business name for comparison.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `pet.getName();` // read the candidate pet name |
| 2 | SET | `String compName = pet.getName();` // store name for matching |

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

> Confirms that the candidate has a usable name and that it matches the requested name without case sensitivity.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `compName != null` // ensure the candidate name exists |
| 2 | EXEC | `compName.equalsIgnoreCase(name)` // compare requested and candidate names |

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

> Applies the optional new-pet exclusion rule before returning the candidate.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `!ignoreNew` // allow all matching pets when filtering is disabled |
| 2 | CALL | `pet.isNew();` // check whether the candidate is unsaved |
| 3 | EXEC | `!pet.isNew()` // permit only persisted pets when filtering is enabled |

**Block 1.2.1.1** — [RETURN] `(return pet;)` (L140)

> Returns the first owner pet that satisfies both the name match and the new-pet rule.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return pet;` |

**Block 2** — [RETURN] `(return null;)` (L144)

> Executes when no eligible pet is found after scanning the full collection.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return null;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain entity | Customer or pet owner aggregate that holds personal details and related pets. |
| `Pet` | Domain entity | An animal registered under an owner’s account. |
| `name` | Field / parameter | Pet display or registration name used for identification. |
| `ignoreNew` | Parameter | Flag that excludes unsaved pets from selection when enabled. |
| `isNew` | State flag | Persistence state indicating that the pet has not been saved yet. |
| `equalsIgnoreCase` | Technical rule | Case-insensitive name matching used to avoid display-case mismatches. |
| `getPets` | Domain association accessor | Returns the owner’s associated pet collection for in-memory searching. |
| `owner` | Business module | The Petclinic area that manages owners and their pets. |
| `Screen` | Architecture term | User-facing controller layer entry point in this documentation style. |
| `Test` | Architecture term | Automated verification code that exercises the same business behavior. |
| CRUD | Technical acronym | Create, Read, Update, Delete — operation classification used for dependency analysis. |
| `persisted` | Business term | Saved to the underlying data store and no longer considered new. |
| `unsaved` | Business term | Created in memory but not yet stored permanently. |
