> For the complete documentation index, see [llms.txt](https://www.pranaypourkar.co.in/the-programmers-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.pranaypourkar.co.in/the-programmers-guide/spring/spring-features/spring-persistence/jpa-java-persistence-api/orm-mapping-annotations/4.-inheritance-mappings.md).

# 4. Inheritance Mappings

## 1. @Inheritance

### About

* `@Inheritance` is an annotation used in **JPA** to define **inheritance mapping strategies** between **entity classes**.
* It specifies **how the inheritance** between **parent** and **child** entity classes should be **mapped** into relational database tables.

### Why Is It Needed?

* In Java, it's natural to use class inheritance for code reuse and modeling hierarchy.
* In relational databases, there is **no native inheritance** — every table is flat.
* So JPA must **simulate inheritance** by **deciding** how to map the class hierarchy to tables.

### Where `@Inheritance` is Used ?

When we have:

* A **base entity class** (abstract or concrete).
* Multiple **subclasses** extending the base.
* We want the inheritance relationship **persisted properly** in DB.

### Syntax of @Inheritance

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Parent {
    // fields
}
```

* `strategy` is mandatory. It tells JPA **which way** to map the hierarchy.

### Inheritance Strategies in JPA

There are **3 official strategies** under `@Inheritance(strategy = ...)`:

<table><thead><tr><th width="311.125">Strategy</th><th>Meaning</th></tr></thead><tbody><tr><td><code>SINGLE_TABLE</code></td><td>One table for all classes.</td></tr><tr><td><code>TABLE_PER_CLASS</code></td><td>One table per concrete class.</td></tr><tr><td><code>JOINED</code></td><td>Multiple tables linked by primary keys.</td></tr></tbody></table>

### 1. InheritanceType.SINGLE\_TABLE

* **All entities in the hierarchy are mapped into a single table**.
* One big table with **columns from parent and child classes**.
* **Discriminator column** is used to differentiate which row belongs to which class.

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public class Employee {
    @Id
    private Long id;
    private String name;
}
```

```java
@Entity
@DiscriminatorValue("manager")
public class Manager extends Employee {
    private String departmentName;
}
```

```java
@Entity
@DiscriminatorValue("developer")
public class Developer extends Employee {
    private String programmingLanguage;
}
```

#### Database Table

<table><thead><tr><th width="75.4453125">id</th><th width="88.7421875">name</th><th width="170.921875">departmentName</th><th>programmingLanguage</th><th>type</th></tr></thead><tbody><tr><td>1</td><td>John</td><td>HR</td><td>NULL</td><td>manager</td></tr><tr><td>2</td><td>Jane</td><td>NULL</td><td>Java</td><td>developer</td></tr></tbody></table>

#### Characteristics

<table><thead><tr><th width="166.21484375">Aspect</th><th>Details</th></tr></thead><tbody><tr><td>Performance</td><td>Fastest (only one table to join).</td></tr><tr><td>Schema</td><td>Sparse columns (many NULLs if many subclasses).</td></tr><tr><td>Flexibility</td><td>Hard to add constraints because unrelated fields exist in same table.</td></tr><tr><td>Discriminator</td><td>Mandatory (<code>@DiscriminatorColumn</code>).</td></tr><tr><td>Example use case</td><td>Small inheritance hierarchies with few fields.</td></tr></tbody></table>

### 2. InheritanceType.TABLE\_PER\_CLASS

* **Each concrete entity** gets its **own table**.
* Each table **duplicates the columns** inherited from parent.
* No need for discriminator column.

```java
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Employee {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
}
```

```java
@Entity
public class Manager extends Employee {
    private String departmentName;
}
```

```java
@Entity
public class Developer extends Employee {
    private String programmingLanguage;
}
```

#### Database Tables

Separate table for each subclass.\
Each table will have own copy of inherited fields.

Manager Table

| id | name | departmentName |
| -- | ---- | -------------- |
| 1  | John | HR             |
| 3  | Bob  | Finance        |

Developer Table

| id | name | programmingLanguage |
| -- | ---- | ------------------- |
| 2  | Jane | Java                |

**Notes**:

* No NULLs.
* Duplicate columns (`id`, `name`) in all tables.
* Querying across all employees needs a **UNION**.

#### Characteristics

<table><thead><tr><th width="171.01171875">Aspect</th><th>Details</th></tr></thead><tbody><tr><td>Performance</td><td>Inserts fast. Queries across hierarchy are slow (UNION needed).</td></tr><tr><td>Schema</td><td>No NULL fields.</td></tr><tr><td>Flexibility</td><td>Good if subclasses are quite different.</td></tr><tr><td>Discriminator</td><td>Not needed.</td></tr><tr><td>Example use case</td><td>When subclasses are very different and rarely queried together.</td></tr></tbody></table>

### 3. InheritanceType.JOINED

* **Parent and child classes have their own tables**.
* Tables are linked via **primary key / foreign key**.
* Fetching a subclass involves a **JOIN**.

```java
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
    @Id
    private Long id;
    private String name;
}
```

```java
@Entity
public class Manager extends Employee {
    private String departmentName;
}
```

```java
@Entity
public class Developer extends Employee {
    private String programmingLanguage;
}
```

#### Database Tables

One table for base class and one for each subclass.\
Tables are linked by primary key = foreign key.

Employee Table (base table)

| id | name |
| -- | ---- |
| 1  | John |
| 2  | Jane |
| 3  | Bob  |

Manager Table

| id | departmentName |
| -- | -------------- |
| 1  | HR             |
| 3  | Finance        |

Developer Table

| id | programmingLanguage |
| -- | ------------------- |
| 2  | Java                |

**Notes**:

* `id` is **Primary Key** and **Foreign Key** in child tables.
* Fetching a full Manager/Developer record requires **JOIN** on `id`.
* Very normalized.

#### Characteristics

<table><thead><tr><th width="218.45703125">Aspect</th><th>Details</th></tr></thead><tbody><tr><td>Performance</td><td>Slower (needs JOINs on select).</td></tr><tr><td>Schema</td><td>Normalized (no NULLs).</td></tr><tr><td>Flexibility</td><td>Best for strict relational modeling.</td></tr><tr><td>Discriminator</td><td>Optional (can use).</td></tr><tr><td>Example use case</td><td>When normalized design is required, and JOIN cost is acceptable.</td></tr></tbody></table>

## 2. @DiscriminatorColumn

### About

`@DiscriminatorColumn` is a JPA annotation used in the context of inheritance mapping in JPA to define a **discriminator column**. It helps in distinguishing between different entities in the same table when the `SINGLE_TABLE` or `JOINED` inheritance strategy is used. This column holds the value that determines which subclass the current row corresponds to.

### Why is it Needed?

* **Inheritance Mapping**: When using **single-table inheritance**, all subclasses are stored in the same table. The **discriminator column** is used to store the type of entity (i.e., the subclass) for each row.
* **Class Differentiation**: In databases, there's no direct concept of inheritance, so JPA uses the **discriminator column** to mark which entity a row belongs to.
* **Performance**: The **discriminator column** avoids using complex joins and makes querying easier and more efficient in the `SINGLE_TABLE` strategy.

### Where is `@DiscriminatorColumn` Used ?

* It is used in the **parent entity class** where inheritance is being mapped.
* It works in the context of `SINGLE_TABLE` or `JOINED` inheritance strategies, where a single table stores all the child entity data (for `SINGLE_TABLE`) or child entities have their own table but still rely on the base entity table (for `JOINED`).

### Syntax

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
    @Id
    private Long id;
    private String name;
}
```

* **name**: Specifies the name of the discriminator column (e.g., `employee_type` in the example).
* **discriminatorType**: Specifies the type of the discriminator column (`STRING`, `INTEGER`, `CHAR`, etc.). Default is `DiscriminatorType.STRING`.

### How It Works ?

* The `@DiscriminatorColumn` defines a **special column** in the table that stores a **discriminator value**.
* The value in this column helps JPA determine which class the row belongs to.
* **`@DiscriminatorValue`** on each subclass specifies the value that will be inserted in the discriminator column for that subclass.

#### Example Scenario with `SINGLE_TABLE` Inheritance:

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
    @Id
    private Long id;
    private String name;
}

@Entity
@DiscriminatorValue("MANAGER")
public class Manager extends Employee {
    private String departmentName;
}

@Entity
@DiscriminatorValue("DEVELOPER")
public class Developer extends Employee {
    private String programmingLanguage;
}
```

#### Database Table Structure (for `SINGLE_TABLE` strategy):

| id | name  | employee\_type | departmentName | programmingLanguage |
| -- | ----- | -------------- | -------------- | ------------------- |
| 1  | John  | MANAGER        | HR             | NULL                |
| 2  | Alice | DEVELOPER      | NULL           | Java                |
| 3  | Bob   | DEVELOPER      | NULL           | Python              |

### Key Characteristics

<table data-full-width="true"><thead><tr><th width="190.51953125">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Purpose</strong></td><td>To distinguish between entities when mapped into a single table (or joined strategy).</td></tr><tr><td><strong>Discriminator Value</strong></td><td>The value in this column helps identify which subclass the row belongs to.</td></tr><tr><td><strong>Column Type</strong></td><td>Can be <code>STRING</code>, <code>CHAR</code>, <code>INTEGER</code>, etc., depending on the data.</td></tr><tr><td><strong>Use Case</strong></td><td>Essential for the <code>SINGLE_TABLE</code> inheritance strategy.</td></tr><tr><td><strong>Defaults</strong></td><td>If not defined, defaults to <code>DTYPE</code> as the column name, and <code>DiscriminatorType.STRING</code> for type.</td></tr><tr><td><strong>Inheritance Type</strong></td><td>Primarily used in <code>SINGLE_TABLE</code> inheritance, but can also be used in <code>JOINED</code>.</td></tr></tbody></table>

### Customizing `@DiscriminatorColumn`

We can further customize the **discriminator column** with additional attributes:

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name = "employee_type",
    discriminatorType = DiscriminatorType.STRING,
    length = 50, // Set the maximum length of the discriminator value
    columnDefinition = "VARCHAR(50) NOT NULL" // Custom SQL definition for the column
)
public class Employee {
    @Id
    private Long id;
    private String name;
}
```

#### Attributes

* **name**: Name of the discriminator column.
* **discriminatorType**: Type of the discriminator value (can be `STRING`, `INTEGER`, etc.).
* **length**: Optional. Specifies the maximum length for the discriminator column (default is 31).
* **columnDefinition**: Optional. Allows for specifying the column's SQL definition.

### When Not to Use `@DiscriminatorColumn`

* **Performance Concerns**: The `SINGLE_TABLE` strategy may become inefficient when there are a lot of fields that are not relevant for certain subclasses, leading to sparse tables with many `NULL` values. In such cases, other strategies like `JOINED` or `TABLE_PER_CLASS` may be more efficient.
* **Complex Inheritance**: If the hierarchy has many deep or unrelated subclasses, managing the `@DiscriminatorColumn` can become difficult, and you might prefer using a different inheritance strategy.

### Best Practices

<table data-full-width="true"><thead><tr><th width="147.17578125">Best Practice</th><th>Details</th></tr></thead><tbody><tr><td><strong>Keep it Simple</strong></td><td>Use <code>SINGLE_TABLE</code> and <code>@DiscriminatorColumn</code> for simple hierarchies. Avoid deep inheritance trees.</td></tr><tr><td><strong>Column Type</strong></td><td>Use <code>DiscriminatorType.STRING</code> for most cases, but if you need a number, use <code>DiscriminatorType.INTEGER</code> or <code>CHAR</code> for efficiency.</td></tr><tr><td><strong>Avoid NULLs</strong></td><td>If you are using <code>SINGLE_TABLE</code> strategy, consider the schema design and avoid having many <code>NULL</code> columns for subclasses that don't need them.</td></tr><tr><td><strong>Customization</strong></td><td>Customize the column definition using <code>columnDefinition</code> if you need more control over how the column is created in the database.</td></tr><tr><td><strong>Clear Naming</strong></td><td>Ensure clear and meaningful values for the discriminator column values using <code>@DiscriminatorValue</code>.</td></tr></tbody></table>

## 3. @DiscriminatorValue

### About

`@DiscriminatorValue` is a JPA annotation used to specify the **value** that will be stored in the **discriminator column** for each subclass of a parent entity when **inheritance** is mapped using `SINGLE_TABLE` or `JOINED` inheritance strategies. The **discriminator column** (defined by `@DiscriminatorColumn`) helps JPA differentiate between different subclasses of the same parent entity in the database.

### Why is `@DiscriminatorValue` Needed?

* **Inheritance Strategy**: It is crucial for the `SINGLE_TABLE` inheritance strategy where all subclasses are stored in the same table. Each subclass needs a **discriminator value** to tell which entity type the row corresponds to.
* **Entity Type Identification**: Without `@DiscriminatorValue`, JPA cannot distinguish between different types of entities stored in the same table.
* **Efficient Data Storage**: Helps in storing and querying different entity types in the same table, which can improve performance and reduce the need for multiple database tables in certain situations.

### Where is `@DiscriminatorValue` Used?

* It is applied on **subclass entities** that inherit from a parent entity using a **single table inheritance strategy** (`SINGLE_TABLE` or `JOINED`).
* Each subclass must declare a value for `@DiscriminatorValue` that is inserted into the discriminator column when an instance of the subclass is persisted.

### Syntax of `@DiscriminatorValue`

```java
@Entity
@DiscriminatorValue("SUBCLASS_NAME")
public class Subclass extends ParentClass {
    // Class implementation
}
```

* **@DiscriminatorValue("SUBCLASS\_NAME")**: Specifies the value that will be stored in the discriminator column for this subclass.

### How It Works ?

* The `@DiscriminatorValue` annotation is applied to **subclasses** in the inheritance hierarchy.
* When an instance of the subclass is saved to the database, JPA inserts the corresponding discriminator value into the discriminator column (defined by `@DiscriminatorColumn` in the parent entity).
* JPA uses the value stored in the discriminator column to identify which subclass the row belongs to when querying the data.

### Example

Consider a scenario where we have an `Employee` superclass and two subclasses: `Manager` and `Developer`.

**Parent Entity**

```java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
    @Id
    private Long id;
    private String name;
    // Getter and Setter methods
}
```

**Subclass 1:** `Manager`

```java
@Entity
@DiscriminatorValue("MANAGER")
public class Manager extends Employee {
    private String departmentName;
    // Getter and Setter methods
}
```

**Subclass 2:** `Developer`

```java
@Entity
@DiscriminatorValue("DEVELOPER")
public class Developer extends Employee {
    private String programmingLanguage;
    // Getter and Setter methods
}
```

**Database Table Structure** (for `SINGLE_TABLE` strategy)

| id | name  | employee\_type | departmentName | programmingLanguage |
| -- | ----- | -------------- | -------------- | ------------------- |
| 1  | John  | MANAGER        | HR             | NULL                |
| 2  | Alice | DEVELOPER      | NULL           | Java                |
| 3  | Bob   | DEVELOPER      | NULL           | Python              |

In this case:

* The `employee_type` column is the **discriminator column**.
* The value `"MANAGER"` is inserted for the `Manager` subclass, and `"DEVELOPER"` for the `Developer` subclass.

### Characteristics of `@DiscriminatorValue`

<table data-full-width="true"><thead><tr><th width="198.67578125">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Purpose</strong></td><td>Specifies the value that will be stored in the discriminator column for a specific subclass.</td></tr><tr><td><strong>Target</strong></td><td>Applied to subclasses in an inheritance hierarchy.</td></tr><tr><td><strong>Inheritance Strategy</strong></td><td>Primarily used in the <code>SINGLE_TABLE</code> inheritance strategy. It can also be used in <code>JOINED</code>.</td></tr><tr><td><strong>Discriminator Column</strong></td><td>The value is inserted into the column defined by <code>@DiscriminatorColumn</code>.</td></tr><tr><td><strong>Value Type</strong></td><td>The value can be a string, integer, or other simple types, based on the discriminator column type.</td></tr><tr><td><strong>Role</strong></td><td>Helps JPA identify which subclass the row in the table represents.</td></tr><tr><td><strong>Required</strong></td><td>Yes, each subclass in a <code>SINGLE_TABLE</code> inheritance strategy must declare a discriminator value.</td></tr></tbody></table>

### Default Behavior of `@DiscriminatorValue`

If `@DiscriminatorValue` is **not specified** on a subclass, JPA will use the **class name** (converted to a string) as the discriminator value by default.

#### Example (Implicit Default):

```java
@Entity
@DiscriminatorValue("MANAGER")
public class Manager extends Employee {
    private String departmentName;
}
```

If `@DiscriminatorValue` were omitted, the discriminator value for `Manager` would be automatically set to `"Manager"`, which is the name of the class.

### Customizing `@DiscriminatorValue`

We can customize the discriminator values to make them more readable and relevant to the domain model.

```java
@Entity
@DiscriminatorValue("HR_MANAGER")
public class HRManager extends Manager {
    private String region;
    // Getter and Setter methods
}
```

In this case, the value `"HR_MANAGER"` will be used for rows representing `HRManager` in the discriminator column.

### When Not to Use `@DiscriminatorValue`

* **Complex Relationships**: When the inheritance hierarchy involves complex relationships, consider using the `JOINED` strategy instead, which splits each class into its own table.
* **Multiple Inheritance**: If the entity hierarchy is deep with many unrelated subclasses, the `SINGLE_TABLE` strategy might become inefficient because of the large number of `NULL` values in the columns.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.pranaypourkar.co.in/the-programmers-guide/spring/spring-features/spring-persistence/jpa-java-persistence-api/orm-mapping-annotations/4.-inheritance-mappings.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
