Skip to content

Installation

Requirements

DependencyVersionNote
Spring Boot3.0+CI tests 3.0, 3.2, 3.3, 3.4.
QueryDSL5.1.0+Both original (com.querydsl) and OpenFeign fork (io.github.openfeign.querydsl 6.x) are supported. CI tests both.
Kotlin1.7+
Java17+

Prerequisites

QueryDSL Q-class generation (APT or KSP) must be configured in your project. See QueryDSL documentation for setup instructions.

Add the Dependency

kotlin
implementation("io.github.harryjhin:querydsl-ktx-spring-boot-starter:1.1.0")
groovy
implementation 'io.github.harryjhin:querydsl-ktx-spring-boot-starter:1.1.0'
xml
<dependency>
    <groupId>io.github.harryjhin</groupId>
    <artifactId>querydsl-ktx-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>

That's it. The starter brings in everything you need.


Module Selection Guide

The library ships three modules. Choose based on your needs:

ModuleWhat it providesWhen to use
querydsl-ktx-spring-boot-starterCore + AutoConfigurationMost projects. Adds a JPAQueryFactory bean automatically.
querydsl-ktxExtension interfaces + QuerydslRepository base classYou already register your own JPAQueryFactory bean and only need the Kotlin extensions.
querydsl-ktx-spring-bootAutoConfiguration onlyYou want the auto-registered JPAQueryFactory but will implement extension interfaces yourself.
kotlin
// Pulls in both querydsl-ktx and querydsl-ktx-spring-boot
implementation("io.github.harryjhin:querydsl-ktx-spring-boot-starter:1.1.0")

Core only

kotlin
// Extension interfaces only, no AutoConfiguration
implementation("io.github.harryjhin:querydsl-ktx:1.1.0")

When to use core only

Use querydsl-ktx alone when:

  • You register JPAQueryFactory with custom JPQLTemplates
  • You use a non-Spring framework
  • You want zero auto-configuration magic

AutoConfiguration

The starter auto-registers a JPAQueryFactory bean with these conditions:

ConditionPurpose
@ConditionalOnClass(JPAQueryFactory)Only activates when QueryDSL is on the classpath
@ConditionalOnSingleCandidate(EntityManagerFactory)Activates when exactly one EntityManagerFactory is present, or one is marked @Primary
@ConditionalOnMissingBeanRespects any custom JPAQueryFactory you define
@AutoConfiguration(after = HibernateJpaAutoConfiguration)Runs after Spring Boot JPA auto-configuration completes

Bean creation:

kotlin
@Bean
@ConditionalOnMissingBean
fun jpaQueryFactory(entityManagerFactory: EntityManagerFactory): JPAQueryFactory =
    JPAQueryFactory(SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory))

SharedEntityManagerCreator produces a transactional EntityManager proxy managed by Spring. This is the same pattern Spring Data JPA uses internally.

Custom JPAQueryFactory

If you register your own JPAQueryFactory bean (e.g., with custom JPQLTemplates), the auto-configuration backs off automatically. No exclusions needed.

kotlin
@Configuration
class QuerydslConfig {
    @Bean
    fun jpaQueryFactory(entityManager: EntityManager) =
        JPAQueryFactory(JPQLTemplates.DEFAULT, entityManager)
}

Multi-datasource Setup

With multiple EntityManagerFactory beans, the one marked @Primary is selected automatically.

kotlin
@Configuration
class DataSourceConfig {

    @Bean
    @Primary
    fun primaryEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("primaryDataSource") dataSource: DataSource,
    ): LocalContainerEntityManagerFactoryBean =
        builder.dataSource(dataSource).packages("com.example.primary").build()

    @Bean
    fun secondaryEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("secondaryDataSource") dataSource: DataSource,
    ): LocalContainerEntityManagerFactoryBean =
        builder.dataSource(dataSource).packages("com.example.secondary").build()
}

With this setup, the auto-registered JPAQueryFactory uses the primary datasource.

To query the secondary datasource, register a separate JPAQueryFactory:

kotlin
@Configuration
class SecondaryQuerydslConfig {

    @Bean
    fun secondaryJpaQueryFactory(
        @Qualifier("secondaryEntityManagerFactory") emf: EntityManagerFactory,
    ): JPAQueryFactory =
        JPAQueryFactory(SharedEntityManagerCreator.createSharedEntityManager(emf))
}

No @Primary Marker

If multiple EntityManagerFactory beans exist without @Primary, the auto-configuration stays inactive. You must register JPAQueryFactory manually.

Verify the Setup

Create a simple repository to confirm everything works:

kotlin
@Repository
class TestRepository : QuerydslRepository<YourEntity>() {

    private val entity = QYourEntity.yourEntity

    fun findAll(): List<YourEntity> =
        selectFrom(entity).fetch()
}

If this compiles and runs, your setup is complete. Head to Quick Start to write your first dynamic query.

GraalVM Native Image

querydsl-ktx provides RuntimeHintsRegistrar for GraalVM native image compatibility. The auto-configuration automatically registers reflection hints needed by the library.

QueryDSL Upstream Limitation

QueryDSL 5.1.0 does not officially support GraalVM native image (querydsl/querydsl#3646). You may need additional reflection configuration for QueryDSL core classes when building native images.