Spring JPA @Enumerated

What is @Enumerated?

@Enumerated is a JPA annotation used to specify how a Java enum should be stored in the database.

Without @Enumerated, Hibernate/JPA must decide how to persist the enum value.


Why Do We Need It?

Consider an enum:

public enum Status {
    ACTIVE,
    INACTIVE,
    PENDING
}

And an entity:

@Entity
public class User {

    @Id
    private Long id;

    private Status status;
}

Question:

How should Hibernate store the value?

ACTIVE
INACTIVE
PENDING

or

0
1
2

This is controlled by @Enumerated.


EnumType.STRING (Recommended)

@Entity
public class User {

    @Id
    private Long id;

    @Enumerated(EnumType.STRING)
    private Status status;
}

Example:

user.setStatus(Status.ACTIVE);

Database:

ID STATUS
1 ACTIVE

Hibernate stores the enum name.


Benefits of STRING

Readable Database

Database value:

ACTIVE

instead of:

0

Much easier to understand and debug.


Safe for Future Changes

Original enum:

public enum Status {
    ACTIVE,
    INACTIVE,
    PENDING
}

Later:

public enum Status {
    ACTIVE,
    SUSPENDED,
    INACTIVE,
    PENDING
}

Database values remain:

ACTIVE
INACTIVE
PENDING

No data corruption.


EnumType.ORDINAL

@Entity
public class User {

    @Id
    private Long id;

    @Enumerated(EnumType.ORDINAL)
    private Status status;
}

Enum:

public enum Status {
    ACTIVE,
    INACTIVE,
    PENDING
}

Stored values:

Enum Stored Value
ACTIVE 0
INACTIVE 1
PENDING 2

Database:

ID STATUS
1 0

Hibernate stores the enum position (index).


Why ORDINAL is Dangerous

Version 1:

public enum Status {
    ACTIVE,
    INACTIVE,
    PENDING
}

Database:

ACTIVE = 0
INACTIVE = 1
PENDING = 2

Later another developer adds:

public enum Status {
    ACTIVE,
    SUSPENDED,
    INACTIVE,
    PENDING
}

Now:

ACTIVE = 0
SUSPENDED = 1
INACTIVE = 2
PENDING = 3

Existing database records become incorrect.

Old value:

1

Previously meant:

INACTIVE

Now means:

SUSPENDED

This causes data corruption.


Industry Best Practice

Always use:

@Enumerated(EnumType.STRING)

unless there is a very specific performance or storage requirement.

Most Spring Boot projects use STRING.


Real-World Example

public enum PaymentStatus {
    INITIATED,
    SUCCESS,
    FAILED,
    REFUNDED
}

Entity:

@Entity
public class Payment {

    @Id
    private Long id;

    @Enumerated(EnumType.STRING)
    private PaymentStatus status;
}

Database:

INITIATED
SUCCESS
FAILED
REFUNDED

Very easy to debug production issues.


What Happens Without @Enumerated?

private Status status;

JPA traditionally defaults to:

EnumType.ORDINAL

Because of this, many teams always explicitly write:

@Enumerated(EnumType.STRING)

to avoid surprises.


Complete Example

public enum OrderStatus {
    CREATED,
    PROCESSING,
    SHIPPED,
    DELIVERED
}
@Entity
public class Order {

    @Id
    private Long id;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;
}

Database:

ID STATUS
1 CREATED
2 SHIPPED
3 DELIVERED

Interview Questions

What does @Enumerated do?

It tells JPA/Hibernate how to store enum values in the database.


Available Types

EnumType.STRING
EnumType.ORDINAL

Which One Should Be Preferred?

EnumType.STRING

because it is safer and more readable.


Why is ORDINAL Dangerous?

Because changing enum order changes stored numeric values and can corrupt existing data.


Memory Trick

ORDINAL

Stores Position

ACTIVE   -> 0
INACTIVE -> 1
PENDING  -> 2

Think:

ORDINAL = ORDER/POSITION

STRING

Stores Name

ACTIVE
INACTIVE
PENDING

Think:

STRING = ENUM NAME

Interview One-Liner

@Enumerated is used to persist Java enums in a database. EnumType.STRING stores the enum name and is recommended because it is readable and safe against enum reordering, whereas EnumType.ORDINAL stores the enum position and can lead to data corruption if enum constants are reordered.


This site uses Just the Docs, a documentation theme for Jekyll.