# 5. Additional Configuration Annotations

## 1. @Transient

### About

`@Transient` is a JPA annotation used to **mark a field or property of an entity that should not be persisted** (saved) in the database.\
In other words, JPA **ignores** this field when reading or writing the entity to the database.

The field will still exist inside the Java object and can be used for temporary, calculated, or helper data — but it **will not be mapped** to any database column.

### Why is `@Transient` Needed?

* **Temporary Fields**: Sometimes you want to maintain a field only for business logic inside your application but don't want it to be stored in the database.
* **Computed Values**: You might want a property that is calculated dynamically from other fields and doesn't need database storage.
* **Helper Variables**: Fields needed for UI, caching, intermediate results, or computations.
* **DTO Enrichment**: When enriching an entity before sending it over the network without affecting database structure.

Without `@Transient`, JPA would assume that every field should be persisted, leading to errors if no matching database column exists.

### Where is `@Transient` Used?

* Inside **Entity** classes (`@Entity`-annotated classes).
* On **fields** or **getter methods** (depending on whether field access or property access is used).
* When you have non-persistent data inside an entity.

### Syntax of `@Transient`

```java
@Entity
public class Employee {

    @Id
    private Long id;

    private String name;

    @Transient
    private int calculatedAge; // Not persisted

    // Getter and Setter methods
}
```

In this example, `calculatedAge` is present in the Java object but not saved to or retrieved from the database.

#### Example: `@Transient` on Getter Method

If we use **property-based access** (annotations on getters instead of fields):

```java
@Entity
public class Product {

    @Id
    private Long id;

    private String name;

    private double price;

    @Transient
    public double getDiscountedPrice() {
        return price * 0.9; // 10% discount
    }
}
```

Here, JPA calls the getter when needed but **never persists** the discounted price.

### How It Works

* During **entity persistence (save)**, JPA **ignores** the `@Transient` field.
* During **entity loading (read)**, JPA **does not populate** the `@Transient` field.
* You are responsible for manually setting or computing the transient field if needed at runtime.

### JPA `@Transient` vs Java `transient` keyword

<table data-header-hidden data-full-width="true"><thead><tr><th width="128.02734375"></th><th width="351.50390625"></th><th></th></tr></thead><tbody><tr><td>Aspect</td><td><code>@Transient</code> (JPA)</td><td><code>transient</code> (Java keyword)</td></tr><tr><td>Purpose</td><td>Ignore field in database persistence</td><td>Ignore field during Java object serialization</td></tr><tr><td>Context</td><td>JPA/Hibernate ORM mapping</td><td>Java <code>Serializable</code> interface</td></tr><tr><td>Effect</td><td>Field not mapped to a database column</td><td>Field not included in a serialized byte stream</td></tr><tr><td>Usage</td><td>Annotate field with <code>@Transient</code></td><td>Use <code>transient</code> keyword before field declaration</td></tr></tbody></table>

{% hint style="info" %}
We can even use both together if you want the field to be neither persisted to the database **nor** serialized to disk.

```java
@Transient
private transient int tempValue;
```

{% endhint %}

## 2. @ElementCollection

### About

In JPA, `@ElementCollection` is used when an entity needs to store a **collection of simple types** (like `String`, `Integer`, etc.) or **Embeddable classes**, **without making them separate entities**.\
Instead of mapping each element to an entity (`@Entity`), the collection elements are **stored in a separate table**, automatically managed by JPA.

* **Simple Type Collection** → Collection of primitive or basic types (e.g., List\<String>).
* **Embeddable Type Collection** → Collection of value objects (`@Embeddable`).

### Why `@ElementCollection` is Needed?

* When we have **multiple simple values** associated with a single entity.
* When we want to avoid creating a full-blown entity for small, dependent data.
* To keep modelling clean for **lightweight data** that doesn't need identity (`@Id`).

Instead of creating separate entities and foreign keys, JPA handles the additional table automatically.

### Where is `@ElementCollection` Used?

* On fields representing **collections** (usually `List`, `Set`, or `Map`).
* Inside an entity class (`@Entity`).
* For **non-entity** elements (simple types or `@Embeddable` types).

### How It Works ?

* JPA creates a **separate table** to store the collection elements.
* It links the records back to the owning entity **using a foreign key**.
* The table is managed automatically: insert, update, delete as part of the parent entity's lifecycle.

### Syntax

Example: Collection of Basic Types

```java
@Entity
public class Employee {

    @Id
    private Long id;

    private String name;

    @ElementCollection
    @CollectionTable(name = "employee_skills", 
                     joinColumns = @JoinColumn(name = "employee_id"))
    @Column(name = "skill")
    private List<String> skills = new ArrayList<>();

    // Getter and Setter methods
}
```

* `skills` is a list of `String`.
* A table called `employee_skills` will be created with:
  * `employee_id` (foreign key)
  * `skill` (the actual skill name)

### Table Mapping Behind the Scenes

**Employee Table:**

| id (PK) | name     |
| ------- | -------- |
| 1       | John Doe |

**Employee\_Skills Table:**

| employee\_id (FK) | skill       |
| ----------------- | ----------- |
| 1                 | Java        |
| 1                 | Spring Boot |
| 1                 | Hibernate   |

### Important Supporting Annotations

<table><thead><tr><th width="177.44140625">Annotation</th><th>Purpose</th></tr></thead><tbody><tr><td><code>@CollectionTable</code></td><td>Defines the table name and join columns for the collection.</td></tr><tr><td><code>@Column</code></td><td>Defines the name of the column that stores the element value itself.</td></tr></tbody></table>

If we **don't specify** `@CollectionTable`, JPA **automatically generates** a table name and foreign key.

### `@ElementCollection` with `@Embeddable`

We can also store **complex value objects** instead of just simple types.

```java
@Embeddable
public class Address {
    private String street;
    private String city;
    private String zipCode;
    // Getter and Setter
}
```

```java
@Entity
public class Customer {

    @Id
    private Long id;

    private String name;

    @ElementCollection
    @CollectionTable(name = "customer_addresses", 
                     joinColumns = @JoinColumn(name = "customer_id"))
    private List<Address> addresses = new ArrayList<>();

    // Getter and Setter methods
}
```

**Here**:

* A `customer_addresses` table will be created.
* It will have columns for `customer_id`, `street`, `city`, `zipCode`.

### How It Is Managed

* **Insertion**: When we save the parent entity, the collection elements are inserted automatically.
* **Deletion**: When we delete or update, the corresponding collection records are handled automatically.
* **No Separate Identity**: Elements are **part of** the parent entity, **they are not independent entities**.

### Characteristics of `@ElementCollection`

<table data-full-width="true"><thead><tr><th width="175.53515625">Aspect</th><th>Details</th></tr></thead><tbody><tr><td>Purpose</td><td>To map collections of simple types or embeddable types.</td></tr><tr><td>Database Behavior</td><td>A separate table is created automatically to store the collection elements.</td></tr><tr><td>Lifecycle</td><td>Tied to the parent entity’s lifecycle.</td></tr><tr><td>Identity</td><td>Elements have no primary key; the parent's foreign key manages the relationship.</td></tr><tr><td>Fetching</td><td>Default is <code>LAZY</code> fetching (loaded only when accessed).</td></tr><tr><td>Operations</td><td>Insert, update, delete are cascaded from the owning entity automatically.</td></tr></tbody></table>

### FetchType in `@ElementCollection`

* By default, `FetchType.LAZY` is applied.
* We can manually make it `FetchType.EAGER` if you want the collection to load immediately.

```java
@ElementCollection(fetch = FetchType.EAGER)
private List<String> skills;
```

{% hint style="info" %}
Use `EAGER` cautiously — it might lead to performance overhead if the collection is large.
{% endhint %}

## 3. @Lob

### About

* In JPA, `@Lob` is used to **map large objects** to database columns.
* It marks a **persistent property or field** to be stored as either:
  * **BLOB** (Binary Large Object) → for binary data like images, files, etc.
  * **CLOB** (Character Large Object) → for large text content.

JPA automatically decides **whether to use a BLOB or CLOB** based on the Java type.

### Why `@Lob` is Needed?

* To store **large amounts of data** (binary or text) in the database without size limitations of standard columns.
* To map fields like:
  * Long textual content (articles, descriptions, logs).
  * Large files (images, videos, PDFs, audio, etc.).

### Where is `@Lob` Used?

* On entity fields of type:
  * `String` (for large text → CLOB)
  * `byte[]` (for binary data → BLOB)
  * `Serializable` objects (if using Java object serialization)
* Inside a class annotated with `@Entity`.

### How It Works ?

* If the field type is `String`, **JPA maps it as a CLOB**.
* If the field type is `byte[]`, **JPA maps it as a BLOB**.
* The corresponding database column is treated as large object storage.

### Syntax of `@Lob`

#### Example: Storing Large Text (CLOB)

```java
@Entity
public class Article {

    @Id
    private Long id;

    private String title;

    @Lob
    @Column(name = "content", columnDefinition = "CLOB")
    private String content;

    // Getter and Setter
}
```

* `content` is a large text field.
* It will be stored as a `CLOB` in the database.

#### Example: Storing Binary Data (BLOB)

```java
@Entity
public class Document {

    @Id
    private Long id;

    private String name;

    @Lob
    @Column(name = "file_data", columnDefinition = "BLOB")
    private byte[] fileData;

    // Getter and Setter
}
```

* `fileData` is a byte array.
* It will be stored as a `BLOB` in the database.

#### Example: Serializable Object

We can serialize Java objects into a `BLOB`.

```java
@Entity
public class Report {

    @Id
    private Long id;

    private String title;

    @Lob
    private Serializable reportData;

    // Getter and Setter
}
```

* `reportData` must be a `Serializable` object.
* Stored as a serialized byte stream in the database.

### Important Points

* **CLOB**: Large character/text storage — Used for things like articles, logs, documentation.
* **BLOB**: Large binary storage — Used for things like images, files, attachments.
* **Lazy Fetching**: LOB fields are usually fetched **lazily** (`FetchType.LAZY`) by JPA providers to avoid memory overload.
* **Size Limitation**: BLOB/CLOB allows **storing very large amounts of data**, beyond the limit of `VARCHAR` or similar standard types.
* **Database Support**: Actual behavior can vary slightly depending on the database (Oracle, MySQL, PostgreSQL, etc.).

### FetchType Behavior for `@Lob`

* According to the **JPA specification**, `@Lob` annotated fields are **recommended** to be lazily fetched.
* But, it **depends on the provider** (Hibernate, EclipseLink, etc.).
* We can **explicitly specify**:

```java
@Lob
@Basic(fetch = FetchType.LAZY)
private byte[] image;
```

### Best Practices for `@Lob`

<table data-full-width="true"><thead><tr><th width="235.421875">Best Practice</th><th>Details</th></tr></thead><tbody><tr><td>Use Lazy Fetching</td><td>To avoid loading large data when not needed.</td></tr><tr><td>Separate Large Data</td><td>If possible, keep LOB data in a separate table to avoid heavy load during regular queries.</td></tr><tr><td>Explicit Column Types</td><td>Use <code>@Column(columnDefinition = "CLOB" or "BLOB")</code> if you want to tightly control DDL generation.</td></tr><tr><td>Optimize Database Storage</td><td>Ensure database tablespace is designed to handle large LOBs properly.</td></tr><tr><td>Handle Streams</td><td>If LOB data is very large, prefer streaming APIs instead of loading everything into memory at once.</td></tr></tbody></table>
