Querying in Kotlin

The querydsl-kotlin module provides Kotlin extension functions that make Querydsl expressions feel natural in Kotlin code. Operator overloading allows you to write queries using standard Kotlin operators.

Maven Integration

Add the following dependency to your Maven project:

<dependency>
  <groupId>io.github.openfeign.querydsl</groupId>
  <artifactId>querydsl-kotlin</artifactId>
  <version>7.1</version>
</dependency>

You also need the Querydsl module for your backend (e.g. querydsl-jpa, querydsl-sql). Code generation works the same as with Java — use the annotation processor for JPA or the Maven plugin for SQL.

Code Generation for Kotlin

There are two ways to generate Q-classes for a Kotlin codebase. Pick based on your build system and how your entities are defined.

Pure Kotlin entities (Gradle, KSP)

If your entities are Kotlin classes, use querydsl-ksp-codegen via the KSP Gradle plugin. KSP runs as part of kspKotlin and emits .kt Q-classes:

plugins {
    kotlin("jvm")
    id("com.google.devtools.ksp") version "<ksp-version>"
    kotlin("plugin.jpa")
}

dependencies {
    implementation("io.github.openfeign.querydsl:querydsl-jpa:7.1")
    ksp("io.github.openfeign.querydsl:querydsl-ksp-codegen:7.1")
}

See the querydsl-ksp-codegen README for the full list of querydsl.* settings (prefix, suffix, package suffix, include/exclude filters).

Mixed Java/Kotlin entities (Gradle, KSP)

When your project mixes Java entities with Kotlin queries, the standard querydsl-apt Java processor doesn’t work cleanly: Gradle compiles Kotlin before Java, so Kotlin code can’t see the Java Q-classes generated by APT. querydsl-ksp-codegen handles this case — it picks up Java @Entity / @Embeddable / @MappedSuperclass classes during kspKotlin and emits Kotlin Q-classes that compile alongside your Kotlin sources.

The Gradle setup is the same as for pure-Kotlin entities — no extra configuration is needed beyond keeping your Java entities under src/main/java. The runnable example querydsl-examples/querydsl-example-ksp-codegen mixes Kotlin entities (Person, Cat, …) with a Java entity (Branch, self-referencing), all queried side-by-side from Kotlin tests.

Pure Kotlin entities (Maven, KAPT)

KSP is not natively supported by kotlin-maven-plugin. On Maven, use KAPT with querydsl-kotlin-codegen (which produces the same Kotlin Q-classes via the legacy APT pipeline). See querydsl-examples/querydsl-example-kotlin-codegen for a Maven-based reference.

Java entities only

If your entities and queries are both Java, stick with querydsl-apt — nothing on this page applies.

Kotlin Operator Extensions

The querydsl-kotlin module provides operator overloads for Querydsl expressions, enabling idiomatic Kotlin syntax.

Boolean Operations

import com.querydsl.kotlin.*

val customer = QCustomer.customer

// Standard Querydsl          Kotlin alternative
customer.active.not()       // !customer.active
customer.active
  .and(customer.verified)   // customer.active and customer.verified
customer.active
  .or(customer.verified)    // customer.active or customer.verified

Comparison Operations

// Standard Querydsl          Kotlin alternative
customer.age.lt(5)          // customer.age < 5    (not supported as operator)
customer.age.loe(5)         // customer.age <= 5   (not supported as operator)
customer.age.gt(5)          // customer.age > 5    (not supported as operator)
customer.age.goe(5)         // customer.age >= 5   (not supported as operator)
customer.age.negate()       // -customer.age

Numeric Operations

// Standard Querydsl              Kotlin alternative
customer.age.add(3)             // customer.age + 3
customer.age.subtract(3)        // customer.age - 3
customer.age.multiply(3)        // customer.age * 3
customer.age.divide(3)          // customer.age / 3
customer.age.mod(5)             // customer.age % 5

These operators work with both expressions and literal values:

// With another expression
customer.age + customer.bonusYears

// With a literal
customer.age + 3

String Operations

// Standard Querydsl                    Kotlin alternative
customer.firstName.append("X")       // customer.firstName + "X"
customer.firstName.append(suffix)    // customer.firstName + suffix
customer.firstName.charAt(0)         // customer.firstName[0]

Example Queries

JPA with Kotlin

val customer = QCustomer.customer

// Simple query
val bobs: List<Customer> = queryFactory.selectFrom(customer)
    .where(customer.firstName.eq("Bob"))
    .fetch()

// Using Kotlin operators for complex conditions
val results = queryFactory.selectFrom(customer)
    .where(
        customer.firstName.eq("Bob")
            .and(customer.age + 5 > customer.minAge)
    )
    .orderBy(customer.lastName.asc())
    .fetch()

SQL with Kotlin

val employee = QEmployee.employee

val names = queryFactory.select(employee.firstName + " " + employee.lastName)
    .from(employee)
    .where(employee.salary * 12 > 100_000)
    .fetch()

Using with Other Backends

The Kotlin extension functions work with any Querydsl backend — JPA, SQL, R2DBC, MongoDB, or Collections. Import com.querydsl.kotlin.* and the operators become available on all expression types.