Home/Learn/Hibernate & JPA/Inheritance — Single Table Strategy

Inheritance — Single Table Strategy

Intermediate
Inheritance

All subclass data is stored in one table with a DTYPE discriminator column; best performance (no joins) but wastes space with many nullable columns for sparse hierarchies.

Overview

SINGLE_TABLE is Hibernate's default inheritance strategy when @Inheritance is not specified. All concrete subclass data is stored in one table alongside the base class columns. A discriminator column (default name DTYPE, type VARCHAR) identifies which subclass a row represents. This is the fastest strategy at query time (no joins required) but results in many nullable columns for subclass-specific fields, which cannot be NOT NULL at the DB level. Best suited for shallow, sparse hierarchies with few subclass-specific fields.

Declaring Single Table Inheritance

Annotate the base class with @Inheritance(strategy=SINGLE_TABLE) and @DiscriminatorColumn. Each subclass provides a @DiscriminatorValue.

Java — SINGLE_TABLE inheritance with discriminator
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "payment_type", discriminatorType = DiscriminatorType.STRING)
@Table(name = "payments")
public abstract class Payment {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, precision = 10, scale = 2)
    private BigDecimal amount;

    private LocalDateTime createdAt;
}

@Entity
@DiscriminatorValue("CARD")
public class CardPayment extends Payment {
    private String cardLastFour;    // nullable at DB level — not present for other types
    private String cardBrand;
}

@Entity
@DiscriminatorValue("BANK")
public class BankPayment extends Payment {
    private String accountNumber;
    private String sortCode;
}

Polymorphic Queries

Querying the base class returns all subclass instances. Hibernate adds a WHERE payment_type IN ('CARD', 'BANK') filter automatically. You can query a specific subclass directly.

Java — polymorphic queries on SINGLE_TABLE
// Returns all Payment rows (all types) — single SELECT, no joins
List<Payment> all = em.createQuery("SELECT p FROM Payment p", Payment.class).getResultList();

// Returns only CardPayment rows — WHERE payment_type = 'CARD'
List<CardPayment> cards = em.createQuery(
    "SELECT p FROM CardPayment p", CardPayment.class).getResultList();

// Spring Data — polymorphic repository
public interface PaymentRepository extends JpaRepository<Payment, Long> {}
// paymentRepository.findAll() returns mixed list of CardPayment and BankPayment

Trade-Offs vs Other Strategies

Choose SINGLE_TABLE when the hierarchy is shallow and subclass columns are few. Avoid it for large hierarchies with many nullable columns — it leads to wide, sparse tables that are hard to evolve.

Java — inheritance strategy trade-offs
/*
 * Strategy comparison:
 *
 * SINGLE_TABLE
 *   + No joins — best query performance
 *   + Simple schema — one table
 *   - All subclass columns are nullable at DB level
 *   - Table grows wide with many subclasses
 *
 * JOINED
 *   + Normalised — subclass columns can be NOT NULL
 *   + Clean schema
 *   - JOIN per subclass level on every query
 *
 * TABLE_PER_CLASS
 *   + Subclass columns can be NOT NULL
 *   - Polymorphic queries use UNION ALL — expensive
 *   - ID generator must be TABLE or SEQUENCE (not IDENTITY)
 *
 * Rule of thumb:
 *   Shallow hierarchy + few subclass fields    → SINGLE_TABLE
 *   Data integrity + moderate query complexity → JOINED
 *   Avoid TABLE_PER_CLASS unless read-only
 */

Key Points to Remember

  • 1SINGLE_TABLE stores all subclasses in one table with a discriminator column (default: DTYPE)
  • 2No joins required — fastest query performance of all three inheritance strategies
  • 3Subclass-specific columns cannot be NOT NULL at the DB level (nullable for other types)
  • 4@DiscriminatorColumn customises the discriminator column name and type
  • 5@DiscriminatorValue on each subclass sets its discriminator string
  • 6Best for shallow hierarchies with few subclass fields; avoid for large sparse schemas

Interview Questions

Sign in to ask Aria
1

What is the DTYPE column in Hibernate and what controls it?

EasyTCS
2

Why can't subclass columns have NOT NULL constraints in SINGLE_TABLE strategy?

MediumInfosys
3

How does Hibernate filter rows when querying a specific subclass?

MediumWipro
4

When would you choose SINGLE_TABLE over JOINED inheritance?

MediumAmazon
5

What SQL does a polymorphic query produce for SINGLE_TABLE vs JOINED strategy?

HardOracle

Ask Aria about Inheritance — Single Table Strategy

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…