Binds a GraphQL OBJECT or INPUT_OBJECT to an existing Java class. The class supplies the runtime carrier: rows materialise into the class on the read path, and inputs deserialize into the class on the mutation path. The class shape determines the variant the rewrite picks: a jOOQ TableRecord produces a JooqTableRecordType (output) / JooqTableRecordInputType (input), a jOOQ Record produces a JooqRecordType / JooqRecordInputType, and a plain Java record or POJO produces JavaRecordType / PojoResultType / JavaRecordInputType / PojoInputType.
@record is also the seam between jOOQ-driven generation and developer-supplied containers. Service methods (@service) often return a Java record to combine multiple result shapes; child fields on a @record parent can reach back into the database via @reference (jOOQ-record parents) or via @sourceRow plus a typed accessor (plain-record parents).
SDL signature
directive @record(record: ExternalCodeReference) on OBJECT | INPUT_OBJECT
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
|
|
(required in practice) |
Points at the backing Java class. Only |
Canonical examples
A jOOQ-backed @record (JooqTableRecordType): the type’s instances are jOOQ FilmRecord values, and child fields can reach further tables via @reference because the catalog supplies FK metadata.
type FilmDetails @record(record: {className: "no.sikt.graphitron.rewrite.test.jooq.tables.records.FilmRecord"}) {
title: String! @field(name: "title")
language: [Language!]! @reference(path: [{key: "film_language_id_fkey"}])
}
A plain-Java-record @record (JavaRecordType) backed by a service-returned DTO. The catalog has no FK metadata for a hand-written class, so a child @table-returning field needs an explicit batch-key path: either @reference is unavailable here, or — when the parent only carries the FK column as a primitive field — @sourceRow extracts the key:
type CreateFilmPayload @record(record: {className: "no.sikt.graphitron.rewrite.test.services.CreateFilmPayload"}) {
languageId: Int!
language: [Language!]!
@sourceRow(
className: "no.sikt.graphitron.rewrite.test.services.CreateFilmPayloadLifter",
method: "liftLanguageId"
)
}
A plain-Java-record @record whose canonical Java accessor returns a typed list of jOOQ records. The classifier auto-derives the batch-key from the typed accessor; no @sourceRow is needed:
type CreateFilmsPayload @record(record: {className: "no.sikt.graphitron.rewrite.test.services.CreateFilmsPayload"}) {
films: [Film!]!
}
Input-side @record for service / mutation arguments. The Maven plugin can scaffold a Java record with the same field shape; on the input side the plugin uses the class’s setters / canonical constructor to bind GraphQL input fields:
input EditCustomerInput @record(record: {className: "some.path.JavaCustomerRecord"}) {
id: ID!
firstName: String @field(name: "FIRST_NAME")
email: String
}
Constraints
-
The argument is required in practice. A bare
@record(norecord:) gives the rewrite no class to bind to and is rejected at classify time. -
argMapping:on therecordreference is structurally inert and is rejected at parse time with "argMapping is not supported on@record`". `@recorddoes not consume GraphQL-argument-bound parameters. -
On input types,
@recorddominates@table. When both are present,@tableis ignored, the input classifies as a@record-only input, and a build warning names the shadowed directive. Remove the@tabledeclaration to silence it. -
On object types,
@recordand@tabledo not co-occur: the type is either jOOQ-table-bound (TableType) or backed by a Java class (ResultType). Mixing them is a classification error. -
A child
@table-returning field on a plain-Java-record parent (no jOOQ FK metadata) requires either:-
a typed accessor on the backing class returning the corresponding jOOQ table record (the classifier auto-derives an
AccessorKeyedbatch key), or -
an explicit
@sourceRowsupplying the lift function and target columns.A bare child reference on such a parent is rejected with
RecordTableField (or RecordLookupTableField) requires a FK join path and a typed backing class for batch key extraction.
-
-
@sourceRowis rejected on jOOQ-record parents — the catalog already supplies the path. Use@referencethere instead. -
When a
@recordtype is reachable from@serviceand contains@table-returning fields, the rewrite emits the re-entry queries automatically; explicit@splitQueryis not required on those child fields.
See also
-
@tableis the catalog-bound counterpart. Choose@tablewhen jOOQ already represents the backing class; choose@recordwhen the carrier is a hand-written Java record/POJO or you want a different jOOQ row type than@tablewould resolve. -
@serviceis the most common upstream of@recordoutput types: the service method returns the Java class, and the resolver projects through it. -
@sourceRowsupplies the missing FK path for child@tablefields on plain-Java-record parents. -
How-to: Result-type variants covers
JavaRecordType/PojoResultType/JooqRecordType/JooqTableRecordTypeand how the rewrite picks among them.