Enums
Database
String
Data Storage
Programming Tips

How to save enum in database as string

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Saving an enum as a string in the database is usually safer than saving its numeric ordinal. String storage makes the data readable and avoids silent corruption when enum members are reordered later in code.

Why String Storage Is Safer Than Ordinals

Suppose you start with this enum:

java
1public enum Status {
2    NEW,
3    ACTIVE,
4    ARCHIVED
5}

If an ORM stores ordinals, NEW might become 0, ACTIVE might become 1, and ARCHIVED might become 2. That looks compact, but it is fragile. If someone later inserts PAUSED between NEW and ACTIVE, the old stored numbers now point to the wrong meaning.

String storage avoids that problem because the database stores NEW, ACTIVE, or ARCHIVED directly. Reordering the enum in code no longer changes existing records.

Map Enums to Strings in Common ORMs

In JPA, use EnumType.STRING explicitly:

java
1import jakarta.persistence.Entity;
2import jakarta.persistence.EnumType;
3import jakarta.persistence.Enumerated;
4import jakarta.persistence.GeneratedValue;
5import jakarta.persistence.Id;
6
7@Entity
8public class Project {
9    @Id
10    @GeneratedValue
11    private Long id;
12
13    @Enumerated(EnumType.STRING)
14    private Status status;
15}

In Entity Framework Core, configure a string conversion:

csharp
1public enum Status
2{
3    New,
4    Active,
5    Archived
6}
7
8protected override void OnModelCreating(ModelBuilder modelBuilder)
9{
10    modelBuilder.Entity<Project>()
11        .Property(p => p.Status)
12        .HasConversion<string>();
13}

In SQLAlchemy, define the enum with explicit string values:

python
1import enum
2from sqlalchemy import Column, Enum, Integer
3from sqlalchemy.orm import declarative_base
4
5Base = declarative_base()
6
7
8class Status(enum.Enum):
9    NEW = "NEW"
10    ACTIVE = "ACTIVE"
11    ARCHIVED = "ARCHIVED"
12
13
14class Project(Base):
15    __tablename__ = "projects"
16
17    id = Column(Integer, primary_key=True)
18    status = Column(Enum(Status), nullable=False)

The implementation varies by framework, but the design goal is the same: keep stored values stable and readable.

Plan for Renames and Legacy Data

String storage is safer, but it is not magic. If you rename an enum constant that is already persisted, the database still contains the old text. That means renames need a migration plan.

A safe rollout usually looks like this:

  1. add support for both old and new names temporarily
  2. migrate stored rows to the new value
  3. remove the backward-compatibility alias

If you need database values that differ from code identifiers, use an explicit converter instead of relying on the enum constant name itself.

java
1public enum Status {
2    NEW("new"),
3    ACTIVE("active"),
4    ARCHIVED("archived");
5
6    private final String dbValue;
7
8    Status(String dbValue) {
9        this.dbValue = dbValue;
10    }
11
12    public String dbValue() {
13        return dbValue;
14    }
15}

That pattern gives you freedom to keep storage values stable even if enum constant names need refactoring.

Common Pitfalls

The biggest mistake is accepting the ORM default without checking whether it stores ordinals. Many frameworks choose the compact representation unless you configure them otherwise.

Another common issue is renaming enum constants without a data migration. String storage protects you from reordering, not from changing the stored text itself.

People also underestimate schema design. If the column is too short, future enum additions can fail unexpectedly. Give the text column reasonable headroom.

Finally, do not use enum string storage as an excuse to skip validation. Unknown values should still be rejected or handled explicitly when reading from the database.

If the enum crosses service boundaries, document the persisted string values as part of the contract. That prevents accidental changes during refactors in one codebase.

Summary

  • Saving enums as strings is usually safer than saving numeric ordinals.
  • String storage prevents data drift when enum members are reordered in code.
  • Configure your ORM explicitly, because defaults are not always safe.
  • Renaming persisted enum values still requires a migration plan.
  • Use explicit converters when storage values should stay stable across code refactors.

Course illustration
Course illustration

All Rights Reserved.