# Eo / Ejb / Example

The `eo.ejb.example` package is a demonstration subpackage that showcases two common Java EE / EJB patterns: JPA entity mapping and dynamic class loading via reflection. It serves as a reference for how to define persistent entities and load classes at runtime by name.

## Overview

This package contains two classes that illustrate foundational patterns used in enterprise Java applications:

- **Entity mapping** — a simple JPA entity class annotated with `@Entity` and `@Table`, demonstrating how to declare a persistent domain model backed by a relational table.
- **Dynamic loading** — a utility class that demonstrates loading and instantiating classes at runtime using Java reflection (`Class.forName` + `newInstance`).

Together these two classes represent a small but representative slice of EJB development: defining data models and loading them dynamically.

## Key Classes and Interfaces

### [EntityClass](eo/ejb/example/EntityClass.java)

A JPA entity class mapped to the database table `entity_class`.

**Purpose:** `EntityClass` models a simple domain object with two fields — an identifier (`id`) and a name (`name`). It is annotated with `@Entity` so that JPA providers (such as Hibernate, EclipseLink, or the built-in persistence unit of the application server) will manage its lifecycle, and with `@Table(name = "entity_class")` to declare the target database table.

**Fields:**

| Field | Type | JPA Annotation | Database Column |
|-------|------|----------------|-----------------|
| `id` | `Long` | `@Id` | Primary key (table-generated) |
| `name` | `String` | `@Column(name = "item_name")` | Column named `item_name` |

**Key methods:**

- `getId()` — Returns the `Long` identifier for this entity. This is the primary key as declared by `@Id`.
- `getName()` — Returns the `String` name stored in the `item_name` column.

**Relationships:** `EntityClass` has no explicit relationships (`@ManyToOne`, `@OneToMany`, etc.) to other entities. It is a standalone entity.

### [PatternOneVar](eo/ejb/example/PatternOneVar.java)

A utility class that demonstrates dynamic class loading via Java reflection.

**Purpose:** `PatternOneVar.load(String clsName)` demonstrates the runtime pattern of resolving a fully-qualified class name from a string, loading the class into the JVM, and creating a new instance. This is a common pattern in frameworks that need to instantiate types not known at compile time — for example, plugin systems, dependency injection containers, or configuration-driven factories.

**Key method:**

- `load(String clsName)` — Takes a fully-qualified class name as a string, dynamically loads the class using `Class.forName(clsName)`, instantiates it with `.newInstance()`, and prints the result. This method throws `Exception` to propagate any errors from class resolution or instantiation (e.g., `ClassNotFoundException`, `InstantiationException`, `IllegalAccessException`).

**How it works — step by step:**

1. The caller passes a fully-qualified class name (e.g., `"com.example.MyPlugin"`) as `clsName`.
2. `Class.forName(clsName)` asks the classloader to resolve and load the class by that name. If the class cannot be found, a `ClassNotFoundException` is thrown.
3. `.newInstance()` calls the class's no-argument constructor to create an instance. If the class has no public no-arg constructor, an `InstantiationException` or `IllegalAccessException` is thrown.
4. The newly created object is printed via `System.out.println()`.

**Note:** `Class.newInstance()` has been deprecated since Java 9 in favor of `Constructor.newInstance()`, which provides better exception handling and control. This pattern is included as a demonstration and should be reviewed if used in production code.

## How It Works

The package does not define a single end-to-end workflow between its classes. Instead, each class is a self-contained illustration of a distinct pattern:

1. **Entity persistence pattern:** `EntityClass` is declared as a JPA entity. When the application starts, the JPA provider scans the persistence unit, finds `@Entity` classes, and maps them to database tables. The `id` field serves as the primary key, and `name` maps to a column named `item_name`. Typical usage would involve a JPA `EntityManager` to `persist()`, `merge()`, or `remove()` instances of this entity.

2. **Dynamic loading pattern:** `PatternOneVar.load()` accepts a string class name and uses reflection to instantiate it at runtime. This pattern is useful when the concrete type is determined by configuration (e.g., a properties file, a database lookup, or user input) rather than being hard-coded.

```mermaid
flowchart TD
    EC["EntityClass<br/>JPA Entity<br/>entity_class table"]
    PV["PatternOneVar<br/>Dynamic Loader<br/>reflection pattern"]
    EC -->|"JPA Entity"| DB[("Database<br/>entity_class table")]
    PV -->|"Class.forName"| CL[Classloader]
    CL -->|"newInstance"| OBJ["Object instance"]
```

## Data Model

`EntityClass` is the only data model in this package:

- **Table:** `entity_class`
- **Primary key:** `id` (type `Long`)
- **Additional column:** `item_name` (type `String`, mapped from the Java field `name`)

The entity has no foreign keys or relationships to other entities. It is a simple, flat data structure suitable for storing named items with a numeric identifier.

## Dependencies and Integration

- **JPA (Java Persistence API):** `EntityClass` depends on `javax.persistence` annotations (`@Entity`, `@Table`, `@Id`, `@Column`). It requires a JPA persistence unit to be configured in the application server or Spring context.
- **Java Reflection:** `PatternOneVar` uses `java.lang.Class.forName()` and `Object.newInstance()`, both of which are part of the standard JDK. No external libraries are needed.
- **No cross-module dependencies:** This package does not import or reference classes from other packages within the application. It is fully self-contained.

## Notes for Developers

1. **`Class.newInstance()` is deprecated.** If you are working with `PatternOneVar` in production code, prefer the modern approach:
   ```java
   Class<?> clazz = Class.forName(clsName);
   Object obj = clazz.getDeclaredConstructor().newInstance();
   ```
   This avoids hiding `InstantiationException` and `IllegalAccessException` inside an `InvocationTargetException`.

2. **No setters on `EntityClass`.** The entity only exposes getter methods (`getId()`, `getName()`). This suggests it is intended for read-only access or that modifications are handled through the JPA `EntityManager` rather than direct field mutation. Ensure any persistence operations go through proper JPA channels.

3. **Exception handling is broad.** `PatternOneVar.load()` declares `throws Exception`, which is overly broad. If this pattern is reused, narrow the exception type to `ReflectiveOperationException` to be more explicit.

4. **Example package.** The `example` naming convention suggests these classes are illustrative. They may not be used in production and could be removed or refactored at any time. Treat them as learning material rather than production code.

5. **Thread safety.** `PatternOneVar` is stateless, so its `load()` method is inherently thread-safe. `EntityClass` is a JPA entity whose lifecycle is managed by the persistence context — follow the standard JPA concurrency rules (do not share entities across threads without proper synchronization).
