Declares that all rows of an interface (or union) live on a single jOOQ table and that one column tells the generator which subtype each row belongs to. Implementing objects pin themselves to that column’s value via @discriminator. The pair drives a single-table polymorphic fetcher: one SELECT against the shared table, branching by discriminator value at row-mapping time.
Use @discriminator together with this directive on every implementing type. For multi-table polymorphism (different tables per implementer), omit @discriminate entirely — the rewrite emits a multi-table fetcher when the interface has no discriminator column.
SDL signature
directive @discriminate(on: String!) on INTERFACE | UNION
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
|
|
(required) |
Name of the column on the interface’s |
Canonical example
The example schema’s Content interface is single-table polymorphic: all rows live in content, and CONTENT_TYPE selects the subtype.
interface Content @table(name: "content") @discriminate(on: "CONTENT_TYPE") {
contentId: Int! @field(name: "CONTENT_ID")
title: String! @field(name: "TITLE")
}
type FilmContent implements Content @table(name: "content") @discriminator(value: "FILM") {
contentId: Int! @field(name: "CONTENT_ID")
title: String! @field(name: "TITLE")
length: Int @field(name: "LENGTH")
rating: MpaaRating @reference(path: [{key: "content_film_id_fkey"}]) @field(name: "RATING")
}
type ShortContent implements Content @table(name: "content") @discriminator(value: "SHORT") {
contentId: Int! @field(name: "CONTENT_ID")
title: String! @field(name: "TITLE")
description: String @field(name: "SHORT_DESCRIPTION")
}
A query selecting … on FilmContent { length } and … on ShortContent { description } produces a single SELECT content.content_id, content.title, content.length, content.short_description, content.content_type FROM content; the row mapper inspects content_type per row and dispatches to the matching type. Subtype-only fields are read as nullable from the unified projection (the row mapper ignores them on the wrong subtype).
Subtype-specific fields may pull from joined tables. FilmContent.rating reaches into film via content_film_id_fkey; the generator emits a conditional LEFT JOIN gated by content_type = 'FILM', so non-FILM rows never trigger the join.
Constraints
-
The interface (or union) must carry
@table; without it there is no shared table to branch on. -
The
oncolumn must exist on that table. The build fails if it does not resolve. -
Every implementing object must declare
@discriminator(value:). Implementers without one are rejected at classify time. -
All implementers must share the interface’s
@table(single-table polymorphism). Implementers on a different table are rejected; for cross-table polymorphism, omit@discriminateand use the multi-table fetcher instead. -
@discriminatecannot be combined with disjoint-table union members. The same single-table requirement applies.
See also
-
@discriminatoris the per-implementer pair: it names the discriminator value that places a row in this subtype. -
@tableestablishes the shared table the discriminator column resolves against. -
@referencefor subtype-specific fields that pull from joined tables (such asFilmContent.ratingin the example). -
How-to: Polymorphic types for the choice between single-table and multi-table fetchers.