# Eo / Ejb / Example

## Overview

The `eo.ejb.example` package is an **example/demo module** showcasing the various Enterprise JavaBean (EJB) component types and related Java EE patterns. It provides one representative class for each major EJB category — stateless session beans, stateful session beans, singleton beans, and message-driven beans — along with a JPA entity and a class demonstrating cross-framework dependency injection. This module serves as a reference for how to structure different bean types, apply common annotations, and mix EJB lifecycle patterns within a single application.

## Key Classes and Interfaces

### Stateless Session Bean

#### [AllAnnotations](AllAnnotations.java)

`AllAnnotations` is a stateless session bean that demonstrates combining multiple bean and REST annotations on a single class.

- **Annotations:** `@Stateless` (EJB), `@Path("/api/annotations")` (JAX-RS), `@GET`, `@POST` (JAX-RS). This class appears to serve dual purpose as both an EJB component and a REST resource.
- **Dependency Injection:** Uses `@Inject` (CDI) to inject `SomeService`. This shows standard CDI injection working inside an EJB context.
- **`toString()`** ([line 18-23](AllAnnotations.java:18)): Returns the string `"AllAnnotations"`. Annotated with `@Override`, `@SuppressWarnings("unused")`, and `@Deprecated`, demonstrating how multiple meta-annotations stack on a method.
- **`restMethod()`** ([line 25](AllAnnotations.java:25)): An empty placeholder method. Given the class's `@Path`, `@GET`, and `@POST` annotations on the class itself, this appears to be a hook for REST endpoint logic.

**Why it matters:** This class illustrates that EJBs can double as JAX-RS resources and that standard Java annotations (`@Deprecated`, `@SuppressWarnings`) coexist naturally alongside Java EE framework annotations.

---

### JPA Entity

#### [EntityClass](EntityClass.java)

`EntityClass` is a JPA persistent entity mapped to a database table.

- **Annotations:** `@Entity` and `@Table(name = "entity_class")`.
- **Fields:**
  - `id` — primary key (`@Id`), type `Long`.
  - `name` — stored in column `"item_name"` (`@Column(name = "item_name")`), type `String`.
- **Getters:**
  - `getId()` ([line 17](EntityClass.java:17)): Returns the `Long` primary key.
  - `getName()` ([line 18](EntityClass.java:18)): Returns the `String` name value.

**Why it matters:** This is a minimal but complete JPA entity example. It uses the `Long` type for the primary key (as opposed to `int` or `int[]`), which is the standard recommended practice for JPA entities. It demonstrates the `@Table` annotation for explicit table naming and `@Column` for column-level mapping overrides.

---

### Message-Driven Bean

#### [MessageBean](MessageBean.java)

`MessageBean` is a message-driven bean (MDB), the EJB equivalent of a JMS message listener.

- **Annotation:** `@MessageDriven` — marks this class as an MDB that will receive asynchronous JMS messages.
- **`onMessage()`** ([line 7](MessageBean.java:7): The message listener entry point. Empty in this example, but in a real application this would contain the logic for processing incoming JMS messages.

**Why it matters:** MDBs provide asynchronous, decoupled message processing. This class shows the simplest possible MDB structure — no constructor, no `messageListenerInterface` specified — which means the container defaults to treating the bean itself as the `MessageListener`.

---

### Multi-Framework Dependency Injection

#### [MultiDIBean](MultiDIBean.java)

`MultiDIBean` demonstrates that a single Java class can accept dependencies injected through multiple frameworks simultaneously — EJB, Spring, and Java EE resource injection.

- **Dependency Injection sources:**
  - `@EJB` — EJB-style injection of `InventoryService`.
  - `@Autowired` — Spring-style injection of `NotificationService`.
  - `@Resource` — JNDI/Java EE resource injection of `DataSource`.
- **No lifecycle methods:** This class has no `@PostConstruct`, `@PreDestroy`, or other EJB lifecycle callbacks. It's a plain class used solely to showcase multi-framework injection.

**Why it matters:** In legacy or hybrid applications, it's common to run EJB containers alongside Spring or other DI containers. This class serves as a reference for how to wire together dependencies from different frameworks in one class.

---

### Singleton Session Bean

#### [SingletonBean](SingletonBean.java)

`SingletonBean` is a singleton session bean — an EJB managed by the container that guarantees exactly one instance per application.

- **Annotation:** `@Singleton`.
- **`init()`** ([line 7](SingletonBean.java:7): An empty method that, in practice, would typically be annotated with `@PostConstruct` to perform one-time initialization when the container creates the singleton instance.

**Why it matters:** Singletons are the go-to choice for shared, application-scoped state or services (caches, counters, configuration holders). Unlike stateless beans (which the container pools and reuses), a singleton has a single shared instance, so thread-safety becomes the developer's responsibility.

---

### Stateful Session Bean

#### [StatefulBean](StatefulBean.java)

`StatefulBean` is a stateful session bean that maintains conversational state across method invocations for a given client.

- **Annotation:** `@Stateful`.
- **`doWork()`** ([line 7](StatefulBean.java:7): An empty placeholder method representing work that relies on bean-held state from previous calls in the same conversation.

**Why it matters:** Stateful beans are useful for multi-step workflows (e.g., a shopping cart, a wizard-style form) where each client needs its own isolated state. The container manages the lifecycle, passivation, and activation transparently.

---

## How It Works

The module does not implement an application-wide workflow; instead, each class is self-contained and demonstrates an independent EJB pattern. Here's how the pieces relate:

```mermaid
flowchart TD
    subgraph EJB_Lifecycle["EJB Lifecycle Types"]
        SLS["Stateless AllAnnotations"]
        SFS["Stateful StatefulBean"]
        Sng["Singleton SingletonBean"]
        MDB["Message Driven MessageBean"]
    end

    subgraph JPA["JPA Entity"]
        ENT["EntityClass"]
    end

    subgraph MultiDI["Multi-Framework DI"]
        MID["MultiDIBean"]
    end

    MID -->|"@EJB dependency"| ENT
    MID -->|"@Resource dependency"| ENT
    SLS -.->|"uses"| ENT
    ENT -->|"maps to table"| DB["entity_class"]
```

### Bean lifecycle summary

| Bean | Annotation | Lifecycle | Shared instance? | Typical use |
|------|-----------|-----------|-------------------|-------------|
| `AllAnnotations` | `@Stateless` | Container pools instances per request | No (stateless) | REST endpoints, utility operations |
| `StatefulBean` | `@Stateful` | One instance per client conversation | No (per-client) | Multi-step workflows, shopping carts |
| `SingletonBean` | `@Singleton` | One instance per application | Yes | Caches, shared counters, app-wide config |
| `MessageBean` | `@MessageDriven` | Container creates instances for JMS messages | No (pooled) | Async message processing |
| `MultiDIBean` | *(none)* | Plain class; DI driven | Depends on injected beans | Cross-framework wiring |

## Data Model

`EntityClass` is the only data model in this module. It maps to the `entity_class` table with two columns:

| Column | Java Type | Purpose |
|--------|-----------|---------|
| `id` | `Long` | Primary key (auto-generated or assigned by the application) |
| `item_name` | `String` | A named attribute stored under a non-default column name |

No other classes in the package persist data. `MultiDIBean` injects a `DataSource` which could be used to interact with `EntityClass` at runtime, but no persistence logic is shown here.

## Dependencies and Integration

### Internal (same package)

There are no direct code dependencies between the classes in `eo.ejb.example`. Each class is standalone. The only conceptual link is through shared types — for example, `MultiDIBean` references `InventoryService`, `NotificationService`, and `DataSource`, while `AllAnnotations` references `SomeService`. These types are presumably defined in other packages.

### External frameworks

The package depends on the following Java EE / Jakarta EE APIs:

- **EJB API** (`javax.ejb.*`) — `@Stateless`, `@Stateful`, `@Singleton`, `@MessageDriven`, `@EJB`
- **JPA API** (`javax.persistence.*`) — `@Entity`, `@Table`, `@Id`, `@Column`
- **CDI** (`javax.inject.*`) — `@Inject`
- **JAX-RS** (`javax.ws.rs.*`) — `@Path`, `@GET`, `@POST`
- **Java EE Common Annotations** (`javax.annotation.*`) — `@Resource`
- **Spring Framework** (`org.springframework.beans.factory.annotation.*`) — `@Autowired` (via `MultiDIBean`)

The presence of `@Autowired` from Spring alongside EJB annotations indicates this module may be used in a hybrid environment where EJB containers coexist with Spring, or it serves as a reference for migration scenarios.

## Notes for Developers

- **All classes are intentionally minimal.** Methods like `onMessage()`, `doWork()`, and `restMethod()` are empty placeholders. In production code, these would contain actual business logic.
- **`AllAnnotations` applies REST annotations at the class level.** The `@Path`, `@GET`, and `@POST` annotations are on the class itself rather than individual methods. This is a JAX-RS pattern that means the class is globally available under `/api/annotations` for both GET and POST — individual methods could further refine HTTP method routing.
- **`@Deprecated` on `toString()`:** The `toString()` override in `AllAnnotations` is marked deprecated, which is unusual since `toString()` is rarely replaced. This appears to be illustrative rather than a real deprecation decision.
- **No cross-module dependencies:** This module does not reference any other package within the codebase. All injected types (`SomeService`, `InventoryService`, `NotificationService`, `DataSource`) come from external dependencies.
- **Thread safety for Singleton:** If `SingletonBean` is extended to hold mutable state, the developer must handle synchronization manually since the container does not provide thread safety guarantees for `@Singleton` beans (unless annotated with `@ConcurrencyManagement(CONCONT)`).
