Minimal Maven Kotlin Querydsl Example
Published
Updated to current versions
Contents
QueryDSL is a neat and practical tool for easy database-access. In this little example I integrated it into a Kotlin-based Spring Boot project built with Maven.
You can look at the code on Github
Requirements
For this example I created a project with Spring Initilizr and chose Kotlin support and the JPA Dependency
Add the current QueryDSL Library to your pom.xml
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.3.1</version>
</dependency>
The Entity
I just required a simple entity to test the generation of Q-classes by QueryDSL. I used Kotlins data class syntax to create a jpa-compatible entity with a few lines.
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
@Entity
data class TestEntity (
val name: String,
val value: Double
) {
@Id @GeneratedValue
val id: Int? = null
}
The Repository
Spring offers easy access to database entities via repositories, this includes QueryDSL Support.
import org.springframework.data.querydsl.QuerydslPredicateExecutor
import org.springframework.data.repository.CrudRepository
interface TestEntityRepository:
CrudRepository<TestEntity, Int>,
QuerydslPredicateExecutor<TestEntity>
The QuerydslPredicateExecutor defines which entities predicate we can use to structure advanced queries.
The Consumers
I created a simple service in which the repository is injected. The main reason for the service is testing if the Q-classes are generated before kotlin classes are processed. If this would not be the case we could not use Q-classes except in test-code.
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
@Service
class TestEntityService @Autowired constructor(
private val testEntityRepository: TestEntityRepository
){
fun getTestEntityByName(name: String): TestEntity? {
return testEntityRepository.findOne(
QTestEntity.testEntity.name.eq(name)
).get()
}
}
Additionally I created a test that uses the QueryDSL support so that I can be sure it works with the default H2 Database Spring-Boot provides.
import junit.framework.TestCase.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringRunner
@RunWith(SpringRunner::class)
@SpringBootTest
class TestEntityRepositoryTest {
@Autowired
private lateinit var testEntityRepository: TestEntityRepository
@Before
fun setup() {
testEntityRepository.save(TestEntity("test", 8.0))
}
@Test
fun test() {
val testEntities = testEntityRepository.findAll()
assertEquals(1, testEntities.count())
}
}
Build script changes
I needed to change the build plugins, so that the Kotlin Annotation Processor in conjunction with QueryDSL creates the needed Q-classes before the sources are compiled
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<compilerPlugins>
<plugin>jpa</plugin>
<plugin>spring</plugin>
</compilerPlugins>
<args>
<arg>-Xjsr305=strict</arg>
</args>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>kapt</id>
<phase>generate-sources</phase>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jpa</classifier>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/test/kotlin</sourceDir>
<sourceDir>target/generated-sources/kapt/test</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
Thats it! After all these changes I could use QueryDSL with my repositories. The test ensures the integration and has a little example on how to use it.