# Eo / Ejb / Example

The `eo.ejb.example` package is a small demonstration package within the EJB layer. It contains a single JPA entity for persistent data storage and a utility class that showcases runtime reflection for dynamic class loading. These examples are intended to illustrate common patterns used elsewhere in the EJB subsystem.

## Overview

This package serves as a reference for two fundamental Java EE / Jakarta EE patterns:

- **JPA Entity mapping** — defining a persistent model class annotated with `@Entity` and `@Table` to represent a database row.
- **Runtime class loading via reflection** — dynamically loading a class by its fully qualified name at runtime.

The module has no child sub-packages and does not depend on other packages within this project. It is a self-contained example.

## Key Classes and Interfaces

### `EntityClass`

**Source:** [`EntityClass.java`](EntityClass.java)

`EntityClass` is a JPA entity that models a single row in the `entity_class` database table. It holds two fields:

| Field | Type | Annotation | Column Name |
|-------|------|------------|-------------|
| `id` | `Long` | `@Id` | (default, matches field name) |
| `name` | `String` | `@Column(name = "item_name")` | `item_name` |

**Key methods:**

- **`getId()`** — Returns the entity's unique identifier. Maps to the primary key of the database table.
- **`getName()`** — Returns the `name` property. The underlying database column is named `item_name`.

**Design notes:**

- The class uses the default JPA column-to-field naming convention for `id` (column name matches the field name).
- The `name` field is explicitly mapped to `item_name` via `@Column(name = "item_name")`, which means the column name differs from the Java field name.
- There are no setters exposed on this class, which suggests it may be intended for read-only access or that mutations happen through the JPA persistence context directly.
- No constructor is defined, so the default no-argument constructor is used (as required by JPA).

### `PatternOneVar`

**Source:** [`PatternOneVar.java`](PatternOneVar.java)

`PatternOneVar` demonstrates dynamic class loading using Java reflection. The single method `load()` accepts a fully qualified class name as a string and attempts to instantiate that class at runtime.

**Key methods:**

- **`load(String clsName) throws Exception`**
  - **Parameter:** `clsName` — the fully qualified name of a class to load (e.g., `"com.example.SomeClass"`).
  - **Returns:** `void`
  - **Side effects:**
    1. Calls `Class.forName(clsName)` to resolve the class by name at runtime.
    2. Calls `newInstance()` on the resolved `Class` object to create a new instance.
    3. Prints the resulting object's `toString()` to standard output via `System.out.println()`.
  - **Throws:** `Exception` — includes `ClassNotFoundException` if the class cannot be found, `InstantiationException` if the class cannot be instantiated, and `IllegalAccessException` if the no-arg constructor is not accessible.

**Design notes:**

- This pattern uses the deprecated `Class.newInstance()` approach. In modern Java (9+), `Class.getDeclaredConstructor().newInstance()` is preferred since `Class.newInstance()` cannot distinguish between checked and unchecked exceptions and always invokes the no-arg constructor.
- The method propagates all exceptions to the caller, which means the caller must handle `ClassNotFoundException`, `InstantiationException`, and `IllegalAccessException` (or broader `Exception`).
- There is no validation or type checking on `clsName` — the caller is responsible for passing a valid, instantiable class name.

## How It Works

This package does not define a request/response flow since it contains neither servlets nor REST endpoints. Instead, the two classes operate independently:

1. **Persistence flow (EntityClass):** When a JPA persistence provider (e.g., Hibernate, EclipseLink) is configured, `EntityClass` instances are managed as persistent entities. A typical flow involves a `EntityManager.persist()` or `EntityManager.find()` call, after which the entity can be read via `getId()` and `getName()`.

2. **Reflection flow (PatternOneVar):** When `load()` is called with a class name, the JVM class loader resolves the class at runtime. An instance is created and its string representation is printed. This pattern is commonly used in frameworks for plugin loading, factory patterns, or configuration-driven object creation.

## Data Model

`EntityClass` maps to a single database table:

```
+---------------------+
|   entity_class      |
+---------------------+
| *id (BIGINT, PK)    |
| item_name (VARCHAR) |
+---------------------+
```

- **`id`** — Primary key, auto-mapped to the `id` column.
- **`item_name`** — The text field storing the entity's name, mapped from the Java field `name`.

There are no foreign keys, relationships, or cascading behavior defined on this entity.

## Dependencies and Integration

| Dependency | Type | Notes |
|------------|------|-------|
| `javax.persistence.Entity` | Annotation | Marks the class as a JPA entity |
| `javax.persistence.Table` | Annotation | Maps the class to the `entity_class` table |
| `javax.persistence.Column` | Annotation | Customizes column name mapping |
| `javax.persistence.Id` | Annotation | Marks `id` as the primary key |

This package does not import or depend on any other classes from this project.

## Notes for Developers

- **Read-only accessors:** The `EntityClass` class exposes only getters. If you need to modify entity state, ensure there is a corresponding setter defined elsewhere or that mutations are performed through the JPA `EntityManager`.
- **Reflection deprecation:** The `PatternOneVar.load()` method uses `Class.newInstance()`, which has been deprecated since Java 9. Consider migrating to `getDeclaredConstructor().newInstance()` if this pattern is extended.
- **Exception handling:** `load()` declares a broad `throws Exception`. Callers should catch and handle specific exception types (`ClassNotFoundException`, `InstantiationException`, `IllegalAccessException`) rather than catching `Exception` broadly.
- **No setters on EntityClass:** The absence of setters means entity mutations would typically happen through the JPA persistence context rather than direct field assignment.
