# Org / Springframework / Samples / Petclinic / Model

## Overview

The `org.springframework.samples.petclinic.model` package contains the shared domain model building blocks used by Petclinic entities. It appears to provide a small inheritance hierarchy for common persistence concerns such as database identity, display names, and person-name fields, plus a validation smoke test that confirms Bean Validation is wired correctly.

This package is intentionally minimal, but it is important because these base classes define conventions used by the rest of the domain layer. New model types can inherit from these classes to get JPA mapping, validation annotations, and a consistent `isNew()` check for persistence workflows.

## Key Classes and Interfaces

### [BaseEntity](src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java:32)

`BaseEntity` is the common superclass for entities that need a database-generated identifier. It is annotated with `@MappedSuperclass`, so JPA treats its mapping metadata as part of subclasses rather than as a standalone table.

#### What it provides

- A single `id` field mapped with `@Id` and `@GeneratedValue(strategy = GenerationType.IDENTITY)`.
- A simple `isNew()` helper that reports whether the entity has been persisted yet.
- `Serializable`, which is a common requirement for persistent domain objects.

#### Methods

- `getId()` returns the current `Integer` identifier.
- `setId(Integer id)` assigns an identifier, typically used by persistence infrastructure.
- `isNew()` returns `true` when `id` is `null`, which is the package’s main signal that an object has not been stored yet.

#### Why it matters

This class centralizes identity handling so subclasses do not repeat the same persistence boilerplate. The `isNew()` method is especially useful in save/update flows that need to distinguish between insert and update behavior.

### [NamedEntity](src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java:30)

`NamedEntity` extends `BaseEntity` and adds a single `name` property for domain objects that are primarily identified by a displayable name.

#### What it provides

- A `name` field mapped with `@Column`.
- A `@NotBlank` constraint, which makes validation reject empty or whitespace-only names.
- A `toString()` implementation that returns the name when available, or `"<null>"` when it is missing.

#### Methods

- `getName()` returns the current name.
- `setName(String name)` updates the name.
- `toString()` returns a stable human-readable label for logging and debugging.

#### Why it matters

This class is a convenience base type for domain objects that need both identity and a validated display name. The `toString()` behavior is deliberately simple and avoids returning `null`, which makes debugging output safer.

### [Person](src/main/java/org/springframework/samples/petclinic/model/Person.java:27)

`Person` models a human being with first and last name fields. It also extends `BaseEntity`, which means it participates in the same identity model as other persistent entities in this package.

#### What it provides

- A `firstName` field with `@Column` and `@NotBlank`.
- A `lastName` field with `@Column` and `@NotBlank`.
- Standard getter and setter methods for both properties.

#### Methods

- `getFirstName()` and `setFirstName(String firstName)` read and write the first name.
- `getLastName()` and `setLastName(String lastName)` read and write the last name.

#### Why it matters

This class captures the shared name fields used by person-like domain records. The validation annotations mean blank names are rejected before persistence or further processing, which keeps the domain model consistent.

### [ValidatorTests](src/test/java/org/springframework/samples/petclinic/model/ValidatorTests.java:35)

`ValidatorTests` is a focused test class that verifies Bean Validation works against the model annotations.

#### What it provides

- A helper method that builds a `LocalValidatorFactoryBean` and initializes it.
- A test that validates a `Person` with an empty first name.

#### Methods

- `createValidator()` returns a configured `Validator` instance backed by Spring’s `LocalValidatorFactoryBean`.
- `shouldNotValidateWhenFirstNameEmpty()` sets up a `Person`, runs validation, and asserts that one violation is produced for `firstName` with the message `"must not be blank"`.

#### Why it matters

This test is a guardrail for framework upgrades. If Hibernate Validator or Bean Validation behavior changes, the package-level constraints will fail here first, which makes regressions easier to spot.

## How It Works

A typical flow through this package looks like this:

1. A concrete domain object inherits from `BaseEntity`, or from `NamedEntity`/`Person` when those properties are needed.
2. JPA uses the mapping metadata from the superclass to persist the inherited `id`, `name`, `firstName`, or `lastName` fields.
3. Validation runs against the annotated fields.
4. `isNew()` is used to determine whether an object has already been assigned an identifier.
5. In tests, `ValidatorTests` creates a validator, instantiates a `Person`, and confirms that blank data triggers a constraint violation.

The package is small, but it establishes a clear model pattern: shared persistence state belongs in a superclass, and business-facing fields carry validation directly on the model.

## Data Model

The model hierarchy is simple:

- `BaseEntity` defines identity through `id`.
- `NamedEntity` extends `BaseEntity` and adds a validated `name`.
- `Person` extends `BaseEntity` and adds validated `firstName` and `lastName`.

### Relationship diagram

```mermaid
classDiagram
class BaseEntity {
  +Integer id
  +Integer getId()
  +void setId(Integer id)
  +boolean isNew()
}
class NamedEntity {
  +String name
  +String getName()
  +void setName(String name)
  +String toString()
}
class Person {
  +String firstName
  +String lastName
  +String getFirstName()
  +void setFirstName(String firstName)
  +String getLastName()
  +void setLastName(String lastName)
}
NamedEntity --|> BaseEntity
Person --|> BaseEntity
```

### Validation and persistence notes

- `@MappedSuperclass` means the inherited fields are part of the JPA mapping, but the superclass itself is not mapped to its own table.
- `@NotBlank` enforces that string fields contain at least non-whitespace content.
- `GenerationType.IDENTITY` suggests the database is responsible for generating identifiers.

## Dependencies and Integration

This module is mostly self-contained and does not expose cross-module relationships in the index provided. Its direct integrations are framework-level:

- **Jakarta Persistence** for JPA mapping annotations such as `@MappedSuperclass`, `@Id`, `@GeneratedValue`, and `@Column`.
- **Jakarta Validation** for constraint annotations such as `@NotBlank`.
- **Spring validation support** in the test class via `LocalValidatorFactoryBean`.
- **JUnit 5** and **AssertJ** in the validation test.

The package-level documentation in [package-info.java](src/main/java/org/springframework/samples/petclinic/model/package-info.java:1) describes the contents as utilities used by the domain, which matches the small, shared-helper nature of these classes.

## Notes for Developers

- `BaseEntity.isNew()` relies entirely on `id == null`. If you assign IDs manually in tests or fixtures, `isNew()` will change behavior accordingly.
- `NamedEntity.toString()` returns `"<null>"` instead of `null`. That is useful for logs, but it also means the string representation does not exactly mirror the underlying field state.
- Validation is embedded in the model itself. If you add new fields to these classes or create new subclasses, consider whether the same `@NotBlank` convention should apply.
- `ValidatorTests` is intentionally narrow. It does not test all constraints; it exists to confirm the validation pipeline still recognizes annotations on the model classes.
- The package is designed for inheritance, so new domain types should follow the same superclass pattern rather than duplicating id or name fields.

## Package Summary

Overall, `org.springframework.samples.petclinic.model` provides the shared persistence and validation primitives for Petclinic domain objects. It keeps identity handling, basic string validation, and simple person/name models in one place so the rest of the application can build richer entities on top of a consistent foundation.
