2. Field/Column Mappings

1. @Id

About

  • @Id marks a field or property as the primary key of the entity.

  • The primary key uniquely identifies each record in the database table.

  • Every entity must have exactly one primary key field annotated with @Id.

Important Points

  • Without @Id, the JPA provider will throw errors — every entity must be identifiable uniquely.

  • The field marked with @Id can be of types like Long, Integer, UUID, String, depending on the application.

  • If no @GeneratedValue is used, the application itself is responsible for setting the ID.

Syntax and Usage

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class Employee {
    @Id
    private Long id;
    private String name;
}

Here, id is the primary key field.

2. @GeneratedValue

About

  • @GeneratedValue is used to automatically generate the value of the primary key field.

  • It works together with @Id.

  • You can specify different strategies for how the IDs are generated.

Important Points

  • Removes manual burden of assigning unique IDs.

  • Allows consistent, reliable primary key generation, even in concurrent environments.

  • Supports multiple generation strategies suitable for different databases.

Syntax and Usage

import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

Strategies for @GeneratedValue

1. GenerationType.AUTO

  • JPA leaves the choice of generation strategy to the JPA provider (like Hibernate).

  • Hibernate will automatically pick the most appropriate strategy depending on the underlying database capabilities.

DB
Strategy selected by Hibernate

MySQL

IDENTITY (Auto Increment)

Oracle

SEQUENCE

H2

SEQUENCE

PostgreSQL

SEQUENCE

Key Points

  • Portable: No need to change the code when changing DBs.

  • Unpredictable: Exact generation behavior depends on DB and provider.

  • Best suited for simple apps or when you don't care about ID mechanism.

Example

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

2. GenerationType.IDENTITY

  • The database handles primary key generation using auto-increment columns.

  • Common in databases like MySQL, PostgreSQL, SQL Server.

How it Works

  • We don't send an ID in the INSERT statement.

  • Database automatically assigns the next number.

  • After the insert, Hibernate/JPA retrieves the generated ID.

INSERT INTO employee (name, department) VALUES ('John Doe', 'IT');
-- DB automatically assigns id = 1

Key Points

  • No need for a separate sequence object.

  • INSERT must happen immediately — Hibernate can't batch inserts easily.

  • Slightly lower performance if we need batch inserts.

  • Not portable across databases (Oracle does not support auto-increment).

Example

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

3. GenerationType.SEQUENCE

  • Uses a database sequence object to generate primary keys.

  • Highly efficient for databases that support sequences (e.g., Oracle, PostgreSQL, H2, DB2).

How it Works

  • Before inserting the row, Hibernate issues a SELECT nextval('sequence_name') to fetch the next available ID.

  • Then it uses this ID in the INSERT statement.

SELECT nextval('employee_seq');
INSERT INTO employee (id, name, department) VALUES (1001, 'John Doe', 'IT');

Key Points

  • Better performance compared to IDENTITY because Hibernate can preallocate IDs.

  • Fully supports batch inserts and optimistic ID fetching.

  • You can customize sequence name, initial value, allocation size using @SequenceGenerator.

  • More flexible and efficient in high-load systems.

Example

@Entity
@SequenceGenerator(name="employee_seq", sequenceName = "employee_sequence", allocationSize=1)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_seq")
    private Long id;
}

Attributes explained

Attribute
Meaning

name

Logical name for sequence generator.

sequenceName

Actual sequence name in DB.

allocationSize

Number of IDs fetched at a time (default = 50). Lower = more DB hits, higher = more memory.

Note: allocationSize > 1 gives better performance because it reduces DB round-trips.

4. GenerationType.TABLE

  • Simulates sequence behavior using a database table.

  • Useful when database does not support sequences or auto-increment (e.g., older DBs).

How it Works

  • A separate table (e.g., hibernate_sequences) stores next available IDs.

  • Before insert, Hibernate selects and updates the value from this table.

Example

SELECT next_val FROM hibernate_sequences WHERE sequence_name = 'employee';
UPDATE hibernate_sequences SET next_val = next_val + 1 WHERE sequence_name = 'employee';

Key Points

  • Works on any database — portable solution.

  • Slow performance compared to SEQUENCE.

  • High risk of contention in high-concurrency environments (locking issues).

  • Should be avoided in very high-traffic systems unless no choice.

Example

@Entity
@TableGenerator(
    name = "employee_gen",
    table = "id_generator",
    pkColumnName = "gen_name",
    valueColumnName = "gen_value",
    pkColumnValue = "employee_id",
    allocationSize = 1
)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "employee_gen")
    private Long id;
}

Explanation of attributes

Attribute
Description

name

Logical name for table generator.

table

Table name used to store keys.

pkColumnName

Column that stores the key name (e.g., "employee_id").

valueColumnName

Column that stores the key value.

pkColumnValue

Specific key for this entity.

allocationSize

How many IDs to allocate at once.

Quick Comparison of Strategies

Strategy
Who generates ID?
Supports Batch Inserts?
Performance
Portability

AUTO

JPA Provider decides

Depends

Medium

High

IDENTITY

Database auto-increment

No

Medium-Low

Low

SEQUENCE

Database sequence object

Yes

High

Medium-High

TABLE

Separate table

No

Low

Very High

3. @Column

About

  • @Column is used to customize the mapping between an entity field and a database column.

  • By default, JPA maps fields to columns of the same name, but @Column lets you override or fine-tune that behavior.

Important Points

  • It controls column name, length, nullable constraints, uniqueness, precision, and scale.

  • It is optional — if not present, JPA assumes default mapping.

  • It improves control over database schema generation.

Syntax and Usage

import jakarta.persistence.Column;

@Entity
public class Employee {
    @Id
    private Long id;

    @Column(name = "emp_name", nullable = false, length = 100)
    private String name;
}

Attributes of @Column

Attribute
Description
Example

name

Maps the field to a different column name.

@Column(name = "emp_name")

nullable

Specifies if the column can contain NULL values. Default is true.

@Column(nullable = false)

unique

Adds a unique constraint to the column.

@Column(unique = true)

length

Defines the maximum column size (for VARCHAR/CHAR). Default is 255.

@Column(length = 100)

insertable

If false, column is not included in SQL INSERTs.

@Column(insertable = false)

updatable

If false, column is not included in SQL UPDATEs.

@Column(updatable = false)

precision

For BigDecimal, defines the total number of digits.

@Column(precision = 10)

scale

For BigDecimal, defines number of digits after decimal point.

@Column(scale = 2)

columnDefinition

Defines DDL directly (rarely used).

@Column(columnDefinition = "TEXT")

Practical Usage Scenarios

  • If your DB column name is different from Java field name, always specify @Column(name = "...").

  • For fields like emails, usernames, use @Column(unique = true).

  • For fields that should not be updated after insert (e.g., created date), use @Column(updatable = false).

  • Use length wisely for optimizing string storage.

  • For monetary values (BigDecimal), define precision and scale to avoid rounding issues.

Last updated

Was this helpful?