# (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 the model-preparation entry point for owner-centric web requests handled by `OwnerController`. Its business responsibility is to resolve the `owner` model attribute before downstream controller methods render a form or process owner-related navigation. When an `ownerId` is not supplied, it creates a new in-memory `Owner` instance so the UI can start a create flow with a blank domain object. When an `ownerId` is supplied, it performs a repository lookup to load the persisted owner and either returns that existing aggregate or fails fast if the requested owner cannot be found.

From a design perspective, the method implements a simple routing/dispatch pattern driven by the presence or absence of the path variable. It acts as a controller-level factory for the `Owner` model object and delegates persistence access to the injected repository instead of embedding data access logic directly in the web layer. In the wider system, this method supports form binding and screen initialization by ensuring that an `owner` object is always available to the MVC framework. The only conditional branch is whether `ownerId` is null, which splits behavior between create-mode initialization and read-by-id retrieval.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["findOwner(ownerId)"]
    COND{"ownerId == null"}
    NEW_OWNER["Create new Owner()"]
    FIND_OWNER["Call owners.findById(ownerId)"]
    OR_ELSE_THROW["orElseThrow IllegalArgumentException"]
    RETURN_OWNER["Return Owner"]
    START --> COND
    COND -->|Yes| NEW_OWNER
    COND -->|No| FIND_OWNER
    FIND_OWNER --> OR_ELSE_THROW
    NEW_OWNER --> RETURN_OWNER
    OR_ELSE_THROW --> RETURN_OWNER
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `ownerId` | `@PathVariable(name = "ownerId", required = false) Integer` | The identifier of the owner record requested by the screen or request path. When omitted or null, the method treats the call as a create flow and returns a new empty owner shell. When provided, it is used as the key for loading an existing owner from persistent storage. |

**Instance fields / external state read by the method:** `this.owners` repository dependency; the persistent owner store accessed through `findById`.

## 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.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| C | `new Owner()` | N/A | Owner | Instantiates a new owner aggregate for create-mode form binding |
| R | `this.owners.findById(ownerId)` | OwnerRepository | Owner | Reads the owner record by primary key from the owner repository |
| R | `orElseThrow(...)` | N/A | Owner | Converts a missing repository result into a business exception for not-found handling |

## 5. Dependency Trace

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 | Screen:OwnerController | `OwnerController` request handling -> `OwnerController.findOwner` | `new Owner() [C] Owner` / `OwnerRepository.findById [R] Owner` |
| 2 | Screen:PetController | `PetController.findOwner` -> `OwnerController.findOwner` | `OwnerRepository.findById [R] Owner` |

## 6. Per-Branch Detail Blocks

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

> Business branch for initializing a new owner versus loading an existing owner.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `ownerId == null ? new Owner() : ...` // evaluate the null-check branch |

**Block 1.1** — THEN `(ownerId == null)` (L66)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `new Owner()` // create a blank owner object for the create flow |
| 2 | RETURN | `return new Owner();` |

**Block 1.2** — ELSE `(ownerId != null)` (L67-L69)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `this.owners.findById(ownerId)` // look up persisted owner by id |
| 2 | CALL | `orElseThrow(() -> new IllegalArgumentException(...))` // fail fast when the owner does not exist |
| 3 | RETURN | `return resolvedOwner;` |

**Block 1.2.1** — Nested failure handling from `orElseThrow` (L68-L69)

| # | Type | Code |
|---|------|------|
| 1 | THROW | `new IllegalArgumentException("Owner not found with id: " + ownerId + ". Please ensure the ID is correct and the owner exists in the database.")` // return an explicit business error when the requested owner is missing |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `Owner` | Domain object | Pet owner aggregate used by the Petclinic application to represent a person who owns pets |
| `ownerId` | Field | Path parameter that identifies the owner record requested by the web request |
| `@ModelAttribute` | Spring MVC annotation | Indicates that the returned owner object should be added to the model for data binding and rendering |
| `@PathVariable` | Spring MVC annotation | Maps a URI path segment to a method parameter |
| `required = false` | Framework setting | Allows the request to omit the owner identifier, enabling create-mode initialization |
| `findById` | Repository method | Retrieves an owner by its primary key from persistent storage |
| `orElseThrow` | Java Optional API | Converts a missing repository result into an exception instead of returning null |
| `IllegalArgumentException` | Java exception | Signals that the request referenced an invalid or missing owner record |
| create flow | Business term | UI path where a new owner is being prepared rather than editing an existing one |
| persisted owner | Business term | Owner record already stored in the database |
| model attribute | MVC term | Object exposed to the view layer for binding and rendering |
