---
title: "OwnerController.processCreationForm"
fqn: "org.springframework.samples.petclinic.owner.OwnerController"
---

# 業務ロジック — OwnerController.processCreationForm() [11 LOC]

| 項目 | 値 |
|-------|-------|
| 完全修飾名 | `org.springframework.samples.petclinic.owner.OwnerController` |
| レイヤー | Controller |
| モジュール | `owner` (パッケージ: `org.springframework.samples.petclinic.owner`) |

## 1. 役割

### OwnerController.processCreationForm()

本メソッドは、ペットクリニック管理システムにおける「新規オーナー登録」画面の送信データを処理するHTTPエンドポイントである。`POST /owners/new` リクエストを受信し、`Owner`エンティティへのマッピングおよびバリデーション済みの入力値を用いて、新しいオーナーの登録フローを実行する。

本メソッドが扱う業務ロジックは2つの分岐に集約される。まず、`BindingResult.hasErrors()` が `true` の場合（バリデーション違反）、エラーメッセージを Flash属性 として格納し、登録フォーム画面へ復帰させる。これにより、ユーザーは入力ミスを修正した上で再送信できる。次に、バリデーションに合格した場合は、`OwnerRepository.save()` を通じて `owners` テーブルへ新規レコードを作成し、`RedirectAttributes` へ成功メッセージを設定した上で、オーナー詳細画面（`/owners/{id}`）へリダイレクトする。

本メソッドが採用している設計パターンは、標準的な Spring MVC の Form Submission Pattern である。`@Valid` アノテーションにより Bean Validation の制約が適用され、`BindingResult` によりバリデーション結果が即時キャッチされる。この「Validate → Error Branch / Success Branch」の分岐パターンは、Spring MVC アプリケーションにおけるフォーム処理のデファクトスタンダードを実装している。本メソッドはシステム全体における唯一のオーナー作成入口ポイントであり、他のコントローラやバッチからは直接呼び出されない（UIからのHTTPリクエストのみ）。

## 2. 処理パターン（詳細業務ロジック）

```mermaid
flowchart TD
    START(["processCreationForm params"])
    VALIDATE["@Valid Owner owner"]
    CHECK_RESULT{result.hasErrors?
バリデーションエラーあり?}
    ADD_ERROR["redirectAttributes.addFlashAttribute('error',
'There was an error...')"]
    RETURN_FORM["return VIEWS_OWNER_CREATE_OR_UPDATE_FORM
→ owners/createOrUpdateOwnerForm"]
    SAVE_OWNER["this.owners.save(owner)
→ OwnerRepository.save(Owner)
[C] owners テーブル"]
    ADD_MESSAGE["redirectAttributes.addFlashAttribute('message',
'New Owner Created')"]
    REDIRECT["return 'redirect:/owners/' + owner.getId()
→ オーナー詳細画面へ"]
    END_NODE(["Return / Next"])

    START --> VALIDATE
    VALIDATE --> CHECK_RESULT
    CHECK_RESULT -- true --> ADD_ERROR
    CHECK_RESULT -- false --> SAVE_OWNER
    ADD_ERROR --> RETURN_FORM
    RETURN_FORM --> END_NODE
    SAVE_OWNER --> ADD_MESSAGE
    ADD_MESSAGE --> REDIRECT
    REDIRECT --> END_NODE
```

## 3. パラメータ分析

| No | パラメータ名 | 型 | 業務的説明 |
|----|---------------|------|---------------------|
| 1 | `owner` | `@Valid Owner` | 新規登録するオーナーの情報。姓（`firstName`）、名（`lastName`）、住所（`address`）、都市（`city`）、電話番号（`telephone`）を含む。`@Valid` により、渡される前に Bean Validation（`@NotBlank`、`@Pattern`）が適用され、制約違反が `BindingResult` に格納される。`Owner` は `Person` を継承し、`Person` は `BaseEntity` を継承している。 |
| 2 | `result` | `BindingResult` | バリデーション結果を保持するオブジェクト。`owner` のバリデーションエラーの有無（`hasErrors()`）をチェックし、エラーが存在する場合はフォーム画面へ復帰させる分岐を決定する。 |
| 3 | `redirectAttributes` | `RedirectAttributes` | リダイレクト先へ一時的にデータを渡すための Flash属性 用のオブジェクト。エラー時（"There was an error..."）と成功時（"New Owner Created"）の両方でメッセージを格納し、次の画面で表示する。 |

本メソッドが参照するインスタンスフィールド:

| フィールド名 | 型 | 業務的説明 |
|-------------|------|---------------------|
| `this.owners` | `OwnerRepository` | Spring Data JPA によるオーナー永続化リポジトリ。`JpaRepository<Owner, Integer>` を継承し、`save()` メソッドで `owners` テーブルへのCRUD操作を実行する。 |

## 4. CRUD操作／呼び出しサービス

### コード解析グラフからの事前抽出エビデンス:

| CRUD | SC / CBS | SCコード | エンティティ / DB | 操作の説明 |
|------|----------|---------|-------------|----------------------|
| R | `BaseEntity.getId` | BaseEntity | - | `BaseEntity` クラスの `getId()` メソッドを呼び出し、登録済みオーナーのIDを取得する（リダイレクトURLの構築用） |

| CRUD | SC / CBS | SCコード | エンティティ / DB | 操作の説明 |
|------|----------|---------|-------------|----------------------|
| C | `OwnerRepository.save(Owner owner)` | - | `owners` (`@Table(name = "owners")`) | Spring Data JPA の `JpaRepository.save()` により、`Owner` エンティティを `owners` テーブルに新規登録（CREATE）する。`owner` 引数にはバリデーションを通過した有効なデータが含まれる。 |
| R | `Owner.getId()` | - | `owners` (`@Table(name = "owners")`) | `BaseEntity` で定義された `getId()` メソッドを呼び出し、`save()` 後に割り当てられたオーナーのIDを取得し、詳細画面へのリダイレクトURLを構築する。 |

**CRUD分類の根拠:**

- **C (Create)**: `OwnerRepository.save()` は `JpaRepository<Owner, Integer>` が提供する標準の Spring Data JPA メソッドであり、引数のエンティティが新規（ID未設定）の場合に `INSERT` を実行する。
- **R (Read)**: `owner.getId()` は、`save()` の結果として割り当てられたIDを読み出すだけの純粋なアクセサであり、テーブルへのクエリは発行しない。

**永続化レイヤーの概要:**

- `OwnerRepository` は `JpaRepository<Owner, Integer>` を継承しており、Spring Data JPA により `owners` テーブルとのJPAマッピングが自動的に生成される。
- `@Table(name = "owners")` により、`Owner` エンティティは `owners` テーブルに対応する。

## 5. 依存関係トレース

| # | 呼び出し元（画面/バッチ） | 呼び出しチェーン（本メソッドまでの全経路） | 終端（SC / CRUD / エンティティ） |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | HTTP: GET /owners/new | `OwnerController.initCreationForm()` → `VIEWS_OWNER_CREATE_OR_UPDATE_FORM` → フォーム画面 → POST /owners/new → `OwnerController.processCreationForm(owner, result, redirectAttributes)` | `OwnerRepository.save() [C] owners` |

本メソッドの呼び出し元は、Spring MVCのルーティングにより自動的に解決される。`@PostMapping("/owners/new")` アノテーションにより、`GET /owners/new` で表示されるフォームからの POST リクエストが本メソッドにディスパッチされる。直接的なJavaメソッド呼び出し元は存在しない（コントローラ層のエントリーポイントのため）。

**本メソッドが呼び出す終端:**

- `result.hasErrors()` — バリデーションエラー有無の判定（`BindingResult` クラス）
- `redirectAttributes.addFlashAttribute(...)` — Flash属性へのメッセージ設定（`RedirectAttributes` クラス）
- `this.owners.save(owner)` — `OwnerRepository.save()` により `owners` テーブルへの INSERT [C]
- `owner.getId()` — `BaseEntity.getId()` により登録IDの取得 [R]
- `String` 型のリダイレクトURL構築: `"redirect:/owners/" + owner.getId()`

## 6. 分岐ごとの詳細ブロック

**ブロック 1** — [IF] `(result.hasErrors())` (L78)

> バリデーションエラーの有無を判定し、エラーが存在する場合はフォーム画面へ復帰する分岐。

| # | 種別 | コード |
|---|------|------|
| 1 | EXEC | `result.hasErrors()` — `BindingResult` のバリデーションエラー有無をチェック |
| 2 | SET | `redirectAttributes.addFlashAttribute("error", "There was an error in creating the owner.")` — フラッシュ属性にエラーメッセージを設定 [-> "error"] |
| 3 | RETURN | `return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;` — フォーム画面へ復帰 [-> `owners/createOrUpdateOwnerForm`] |

**ブロック 2** — [ELSE] `(result.hasErrors() == false)` (L78)

> バリデーションエラーがない場合の正規の処理フロー。

| # | 種別 | コード |
|---|------|------|
| 1 | CALL | `this.owners.save(owner);` — `OwnerRepository.save()` を呼び出してオーナーを新規登録 [C] `owners` テーブル |
| 2 | SET | `redirectAttributes.addFlashAttribute("message", "New Owner Created");` — フラッシュ属性に成功メッセージを設定 [-> "message"] |
| 3 | RETURN | `return "redirect:/owners/" + owner.getId();` — 登録完了後、オーナー詳細画面へリダイレクト |

## 7. 用語集

| 用語 | 種別 | 業務的意味 |
|------|------|------------------|
| `Owner` | Entity | クリニックの飼い主（オーナー）を表すドメインエンティティ。`Person`（`firstName`, `lastName` を保持）を継承し、住所（`address`）、都市（`city`）、電話番号（`telephone`）、および関連するペットのリスト（`pets`）を含む。 |
| `Person` | Entity | 氏名（`firstName`, `lastName`）を持つ基本エンティティ。`BaseEntity` を継承し、`Owner` および他のドメインエンティティの基底クラスとして使用される。 |
| `BaseEntity` | Entity | 全エンティティの基底クラス。`id` フィールド（`Long`）と `getId()` / `setId()` アクセサを提供する。JPA の `Serializable` を実装。 |
| `owners` | テーブル名 | クリニックのオーナー情報を格納するデータベーステーブル。`@Table(name = "owners")` で `Owner` エンティティに対応する。 |
| `OwnerRepository` | Interface | Spring Data JPA による `Owner` エンティティの永続化インターフェース。`JpaRepository<Owner, Integer>` を継承し、`save()`, `findById()`, `findByLastNameStartingWith()` などのクエリメソッドを提供する。 |
| `@Valid` | アノテーション | Bean Validation（JSR-380）のバリデーションを実行するアノテーション。メソッド引数に付与されると、渡される前に `@NotBlank`, `@Pattern` などの制約が検証される。 |
| `BindingResult` | Class | バリデーションの結果（エラー一覧）を保持するSpring Frameworkのクラス。`hasErrors()` でバリデーションエラーの有無を判定できる。 |
| `RedirectAttributes` | Class | Spring MVC のFlash属性（リダイレクト先で一時的に利用可能なメッセージ属性）を管理するクラス。`addFlashAttribute()` でキーと値をペアで設定する。 |
| `VIEWS_OWNER_CREATE_OR_UPDATE_FORM` | Static Field | フォームビューの名前。値は `"owners/createOrUpdateOwnerForm"`。バリデーションエラー時に復帰する登録フォーム画面を指す。 |
| `@PostMapping("/owners/new")` | アノテーション | POST リクエストを `/owners/new` パスにマッピングするSpring MVCのアノテーション。新規オーナー登録フォームの送信を受け付ける。 |
| `@GetMapping("/owners/new")` | アノテーション | GET リクエストを `/owners/new` パスにマッピングするSpring MVCのアノテーション。新規オーナー登録フォーム画面を表示する。 |
| `@Table(name = "owners")` | JPAアノテーション | `Owner` クラスを `owners` テーブルにマッピングするJPAのアノテーション。 |
| `@OneToMany` | JPAアノテーション | `Owner` と `Pet` の1対多関連を定義するJPAのアノテーション。カスケード結合と eager フェッチが設定されている。 |
| `Flash Attribute` | 概念 | リダイレクト後に次のリクエストでのみ有効な一時的なメッセージ属性。セッションを介さずに次の画面へメッセージを渡す仕組み。 |
| `JpaRepository` | Interface | Spring Data JPA が提供する標準リポジトリインターフェース。`save()`, `findById()`, `findAll()` などのCRUDメソッドを定義する。 |