Binds a GraphQL type to a jOOQ-modelled database table so the generator can project columns, build joins, and emit mutations against it.

SDL signature

directive @table(name: String) on OBJECT | INPUT_OBJECT | INTERFACE

Parameters

Name Type Default Description

name

String

type name (case-insensitive)

The jOOQ table identifier. Must match the SQL identifier as it appears in jOOQ’s catalog. Omit when the GraphQL type name already equals the table name. For jOOQ catalogs that span multiple schemas, the value can be qualified as "schema.table" to scope the lookup; an unqualified value is only accepted when exactly one schema in the catalog contains a table with that name.

Canonical example

The tutorial’s Customer type binds to the customer table:

type Customer implements Node @table(name: "customer") @node {
    customerId: Int!     @field(name: "CUSTOMER_ID")
    firstName:  String!  @field(name: "FIRST_NAME")
    address:    Address  @reference(path: [{key: "customer_address_id_fkey"}])
}

A query that selects customers { firstName } produces a SELECT customer.first_name against this binding. Because the type carries @table, every @field-annotated column inside resolves against the customer table by default; nested types like Address re-bind via their own @table and join to Customer through @reference.

For mutations, @table is also required on the input type so the generator knows which table the INSERT, UPDATE, or UPSERT targets:

input FilmCreateInput @table(name: "film") {
    title:      String! @field(name: "title")
    languageId: Int!    @field(name: "language_id")
}

Constraints

  • The name parameter must resolve to a real jOOQ table; the generator fails the build with an unclassified-type error if the catalog has no matching Table class. Use the same case the jOOQ generator emits (typically uppercase for PostgreSQL identifiers, but follow your project’s catalog).

  • When omitted, the generator looks up the jOOQ table by GraphQL type name (case-insensitive). A type named Customer therefore resolves to the customer table without explicit configuration.

  • Containing fields default to the type’s table for column lookup. A nested @table re-binds; an @reference-annotated field hops into the joined table for the duration of that field’s subquery.

  • For multi-schema catalogs, an unqualified name: must be unique across schemas. When the same bare name exists in two or more schemas (event in public and archive, say), the build fails with @table(name: 'event') is ambiguous: defined in schemas [public, archive]; qualify as 'public.event', 'archive.event'. Disambiguate by qualifying explicitly: @table(name: "public.event"). Single-schema consumers see no change; only collision sites are forced to qualify. A genuinely missing name (no schema contains it) falls through to the standard table 'X' could not be resolved in the jOOQ catalog rejection with a Levenshtein-ranked candidate hint.

See also