# (DD26) Business Logic — OwnerController.findOwner() [7 LOC]

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

## 1. Role

### OwnerController.findOwner()

This method is a request-scoped model initializer that resolves the `owner` model attribute before an Owner-related web form or screen is rendered. Its business role is to provide the current Owner aggregate to downstream MVC handlers, ensuring that the UI always has either a persisted Owner loaded by identifier or a new empty Owner object for creation flows. In practical terms, it acts as a routing and dispatch point for owner selection, not as a business calculator or mutator.

The method supports two service categories: a creation path when no `ownerId` is provided, and a retrieval path when an `ownerId` exists in the URL path. It implements a simple conditional dispatch pattern based on parameter presence, with a repository-backed lookup on the persisted branch. When the identifier is absent, it produces a new domain object so that the same controller can serve both registration and edit-oriented workflows without requiring separate entry points.

Within the larger system, this method is a shared MVC entry utility for owner forms and related nested screens. It isolates the logic for mapping a path variable to a domain object and centralizes the error handling for missing records. If the repository lookup fails, it converts the absence into an explicit business exception so the caller receives a clear message that the requested owner record is unavailable.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["findOwner(ownerId)"])
    DECISION{"ownerId is null?"}
    NEW_OWNER["Create new Owner instance"]
    CALL_FIND["Call owners.findById(ownerId)"]
    OPTIONAL_OWNER["Receive Optional<Owner>"]
    DECISION_FOUND{"Owner present in Optional?"}
    RETURN_OWNER["Return existing Owner"]
    THROW_ERROR["Throw IllegalArgumentException - owner not found"]
    END_NODE(["End"])

    START --> DECISION
    DECISION -->|Yes| NEW_OWNER
    DECISION -->|No| CALL_FIND
    NEW_OWNER --> END_NODE
    CALL_FIND --> OPTIONAL_OWNER
    OPTIONAL_OWNER --> DECISION_FOUND
    DECISION_FOUND -->|Yes| RETURN_OWNER
    DECISION_FOUND -->|No| THROW_ERROR
    RETURN_OWNER --> END_NODE
    THROW_ERROR --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `ownerId` | `@PathVariable(name = "ownerId", required = false) Integer` | Owner identifier coming from the request URL path. When it is present, the method loads the matching owner record for edit/view workflows; when it is absent, the method creates a new Owner instance for registration or initialization flows. |

Instance fields or external state read by this method:
- `this.owners` — injected `OwnerRepository` used to retrieve an existing Owner by primary key.

## 4. CRUD Operations / Called Services

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

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

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.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `OwnerRepository.findById` | `OwnerRepository` | `Owner` | Retrieves a single Owner aggregate by its identifier from the persistence layer. |
| C | `new Owner()` | N/A | `Owner` | Instantiates an empty Owner object for create-mode initialization when no owner identifier is supplied. |
| D | `orElseThrow` | N/A | N/A | Converts a missing Owner lookup result into a business exception so the screen flow can stop with a clear error message. |

## 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: `PetController` | `PetController.findOwner` -> `OwnerController.findOwner` | `OwnerRepository.findById [R] Owner` |
| 2 | Controller: `OwnerController` | `OwnerController.findOwner` -> `OwnerRepository.findById` | `OwnerRepository.findById [R] Owner` |

## 6. Per-Branch Detail Blocks

**Block 1** — IF `(ownerId == null)` (L65)

> Initializes a blank Owner for create-flow usage when the request does not specify an existing owner.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return new Owner();` |

**Block 2** — ELSE `(ownerId != null)` (L66-L69)

> Loads an existing Owner from persistence and escalates a clear exception if the record does not exist.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `this.owners.findById(ownerId)` |
| 2 | CALL | `orElseThrow(() -> new IllegalArgumentException("Owner not found with id: " + ownerId + ". Please ensure the ID is correct and the owner exists in the database."))` |
| 3 | RETURN | `return ...` |

**Block 2.1** — IF `(Owner found in Optional)` (L66-L69)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return owner from Optional` |

**Block 2.2** — ELSE `(Owner not found)` (L66-L69)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new IllegalArgumentException("Owner not found with id: " + ownerId + ". Please ensure the ID is correct and the owner exists in the database.")` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|---------------------|
| `ownerId` | Field | Unique owner identifier supplied in the request path and used to retrieve an existing owner record. |
| `Owner` | Entity | Customer/animal owner domain object managed by the PetClinic application. |
| `OwnerRepository` | Repository | Persistence gateway for owner records, exposing lookup and search operations. |
| `Optional` | Technical term | Wrapper indicating that an Owner record may or may not be present in the database. |
| `@ModelAttribute` | Framework term | Spring MVC annotation that places the return value into the model before request handling continues. |
| `@PathVariable` | Framework term | Spring MVC annotation that binds a value from the URL path into a controller method parameter. |
| create-flow | Business term | Screen flow used to initialize a new Owner for data entry. |
| edit-flow | Business term | Screen flow used to load an existing Owner for display or update. |
| persistence layer | Technical term | Database-backed repository layer responsible for reading stored Owner data. |
| IllegalArgumentException | Technical term | Runtime exception used here to signal that the requested owner record could not be found. |
