Models & Repositories
Data classes, the @Repository annotation, SQL mapping, and query patterns.
Models
Models are @Serializable data classes living in core-* modules so both contracts and implementations can reference them.
- Use
@ContextualonUUIDfields for proper serialization context. - Default
idtoUUID.NILfor new entities — the database generates the real ID on insert. - Keep models in the
core-*module, not the implementation module.
Input Types
Input types represent data coming from GraphQL mutations:
Repositories
Repositories are interfaces annotated with @Repository. Each method is annotated with @Query containing raw SQL. KSP generates the full JDBC implementation at compile time.
Named Parameters
SQL parameters use :paramName syntax. When passing a model object, parameter names match the object's properties — :name maps to category.name.
Return Types
| Return type | Behavior |
|---|---|
List<T> | Maps all rows to a list of model objects |
T? | Maps the first row, or returns null if no rows |
T | Maps the first row, throws if no rows |
Unit | Executes the statement without reading results |
returning *
The returning * SQL clause causes the database to return the inserted/updated row. Combined with a model return type, this gives you the entity with database-generated fields:
Batch Lookups
Use any(:ids) with a List parameter for batch lookups — a single SQL query with an array parameter:
@Query functions do not currently support multiple model parameters — only multiple primitive parameters. If you need to pass two model objects, destructure into primitives. This will be fixed in a future release. @Query Options
| Option | Default | Purpose |
|---|---|---|
returnUpdateCount | false | Return the number of affected rows instead of mapping results |
autoCloseResult | true | Automatically close the result set after reading |
autoCloseStatement | true | Automatically close the prepared statement after execution |