-
Notifications
You must be signed in to change notification settings - Fork 4
Directive @primaryKey
The @required directive provides the ability to generate a DSL in such a way that the field
marked with this directive is automatically added to the query. The @primaryKey
directive does the same, but
additionally generates equals
and hashCode
functions for entities by all fields marked with this directive. You
cannot exclude a field marked with this directive from the query. Kobby does not generate __withoutXXX()
methods for
fields marked with such a directive, and does not allow such fields to be excluded using the __minimize()
function. Let define a GraphQL schema:
type Query {
films: Film!
}
type Film {
id: ID!
title: String!
}
This schema allows us to write a query using the generated DSL that looks like this:
val context: ExampleContext = exampleContextOf(createMyAdapter())
val response = context.query {
films {
id()
title()
}
}
response.films.forEach { film ->
println("Film ${film.id} ${film.title}")
}
If we want to generate a DSL that will automatically include the id
field in the query and to generate the equals
and hashCode
functions for the Film
entity using the id
field, we must mark this field with the @primaryKey
directive. Let's modify our schema:
directive @primaryKey on FIELD_DEFINITION
type Query {
films: [Film!]!
}
type Film {
id: ID! @primaryKey
title: String!
}
Now we can write our query like this:
val context: ExampleContext = exampleContextOf(createMyAdapter())
val response = context.query {
films {
title()
}
}
response.films.forEach { film ->
println("Film ${film.id} ${film.title}")
}
The generated DSL will automatically add the id
field to the projection of the Film
query. In addition, the equals
and hashCode
functions will be generated for Film
entity implementation (file entity/impl/FilmImpl.kt
):
internal class FilmImpl(
internal val __innerContext: ExampleContext,
internal val __innerProjection: FilmProjectionImpl,
internal val __innerDto: FilmDto
) : Film {
// ... skipped
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (javaClass != other?.javaClass) {
return false
}
other as FilmImpl
return __innerDto.id == other.__innerDto.id
}
override fun hashCode(): Int = __innerDto.id?.hashCode() ?: 0
// ... skipped
}
By default, the @primaryKey
directive does not affect the DTO layer. Kobby will not generate equals
and hashCode
functions for FilmDto
:
data class FilmDto(
val id: Long? = null,
val title: String? = null
)
To switch on equals
and hashCode
functions generation on DTO layer set kotlin.dto.applyPrimaryKeys
property
to true
.
Gradle:
plugins {
id("io.github.ermadmi78.kobby")
}
kobby {
kotlin {
dto {
applyPrimaryKeys = true
}
}
}
Maven:
<plugin>
<groupId>io.github.ermadmi78</groupId>
<artifactId>kobby-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate-kotlin</goal>
</goals>
<configuration>
<kotlin>
<dto>
<applyPrimaryKeys>true</applyPrimaryKeys>
</dto>
</kotlin>
</configuration>
</execution>
</executions>
</plugin>
And Kobby will generate equals
and hashCode
functions for FilmDto
:
data class FilmDto(
val id: Long? = null,
val title: String? = null
) {
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (javaClass != other?.javaClass) {
return false
}
other as FilmDto
return id == other.id
}
override fun hashCode(): Int = id?.hashCode() ?: 0
}
- The
@primaryKey
directive can only be applied to a field with no arguments. - The
@primaryKey
directive can only be applied to a field that returns a scalar or enum type. - The
@primaryKey
directive cannot be applied to overridden fields. In this case, apply the directive to the base interface field.
In case of violation of any restriction, the directive will be ignored.
In case of a field is marked with several directives at once - @default
, @required
, @primaryKey
, the behavior of
the Kobby Plugin is undefined!