Spring boot isn't serializing kotlin class - spring

I'm trying to build a simple api with spring boot and kotlin. When I make a request to save a new user everything goes well, a new user is persisted, but response body is empty. I don't know why, I return the new user. Please help me to understand why Jackson isn't serializing my kotlin class.
I can assure that the user returned is not null.
Entity:
#Entity
data class User(#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private val id: Long = 0L,
private var createdAt: LocalDateTime = LocalDateTime.now(),
private var enabled: Boolean = false,
private val username: String = "",
private val password: String = "",
private val name: String = "") {
#PrePersist
private fun onCreate() {
this.enabled = true
this.createdAt = LocalDateTime.now();
}
}
Controller:
#RestController
#RequestMapping("users")
class UserController {
#Autowired
private lateinit var userService: UserService
#PostMapping
fun save(#RequestBody user: User): User {
return this.userService.save(user)
}
}
build.gradle:
buildscript {
ext {
kotlinVersion = '1.2.20'
springBootVersion = '2.0.0.RC1'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
}
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'br.com'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
compile("org.jetbrains.kotlin:kotlin-reflect")
//JACKSON
compile "com.fasterxml.jackson.core:jackson-annotations"
compile "com.fasterxml.jackson.core:jackson-core"
compile "com.fasterxml.jackson.core:jackson-databind"
runtime "com.fasterxml.jackson.datatype:jackson-datatype-jdk8"
runtime "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
runtime "com.fasterxml.jackson.module:jackson-module-kotlin"
runtime('mysql:mysql-connector-java')
runtime('org.springframework.boot:spring-boot-devtools')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
application.properties
#DATA SOURCE
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc\:mysql\://localhost:3307/kotlin-library
spring.datasource.username = root
spring.datasource.password =
#JPA
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
#SERVER
server.servlet.context-path=/
#JACKSON
spring.jackson.serialization.indent-output=true
spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.serialization.write-durations-as-timestamps=false

Everything in your data class is private. Typically serialization ignores private members in a class. If you make the necessary fields you desire to get serialized public, or just remove the private keyword I'm betting it works for you.

Related

How to test exception with JUnit 5 if assertThrows is not catching the exception (Kotlin)

I am writing a test explanation, of which I have done this plenty of times, and I am getting strange behavior. I run the test and then I get:
No username
com.bsb.pr.test.domain.UserException: No username
at app//com.bsb.pr.test.service.UserService.fetchUserById(UserService.kt:21)
at app//com.bsb.pr.test.UserServiceTestNoKSpock.getUserNameById throws exception if username is null(UserServiceTestNoKSpock.kt:23)
at java.base#17.0.4/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
The follow is the code that is used:
#Service
class SubscriptionService {
fun getSubscriptionByUserId(id: Number): Subscription? {
return Subscription("email#email.com")
}
}
#Service
class UsernameService {
fun getUserNameById(id: Number): Username? = Username("test")
}
Focal Service
#Service
class UserService(
private val usernameService: UsernameService,
private val subscriptionService: SubscriptionService
) {
fun fetchUserById(id: Number): User {
val username: Username =
usernameService
.getUserNameById(id)
?: throw UserException("No username")
val subscription: Subscription =
subscriptionService
.getSubscriptionByUserId(id)
?: throw UserException("No subscription")
return User(id, username.content, subscription)
}
}
Focal test
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.mockito.Mockito
class UserServiceTest {
private val usernameService: UsernameService = Mockito.mock(UsernameService::class.java)
private val subscriptionService: SubscriptionService = Mockito.mock(SubscriptionService::class.java)
private val userService = UserService(usernameService, subscriptionService)
#Test
fun `getUserNameById throws exception if username is null`() {
// setup mocks
Mockito.`when`(userService.fetchUserById(1)).thenReturn(null)
// whenever
val userException: UserException = assertThrows { userService.fetchUserById(1) }
assert(userException.message == "No username")
Mockito.verify(userService).fetchUserById(1)
}
}
build.gradle
plugins {
id("org.springframework.boot") version "2.7.5"
id("io.spring.dependency-management") version "1.0.15.RELEASE"
kotlin("jvm") version "1.6.21"
kotlin("plugin.spring") version "1.6.21"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
I have tried different forms of that assertThrows and looked at other online documentation.
It should notice the exception and then pass.

Spring Data MongoDB can't use #Transactional of my Repository Test: Failed to retrieve PlatformTransactionManager for #Transactional test

I am starting a simple spring web service that uses Spring Data MongoDB. I am used to use Spring Data with MySQL and here using #Transactional in my test classes works fine.
However in this case I receive the following error message:
Failed to retrieve PlatformTransactionManager for #Transactional test: [DefaultTestContext#39277750 testClass = ItemRepositoryTest, testInstance = com.ruckpack.equipmentservice.repository.ItemRepositoryTest#73bbbc73, testMethod = should test#ItemRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration#2c217989 testClass = ItemRepositoryTest, locations = '{}', classes = '{class com.ruckpack.equipmentservice.EquipmentServiceApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer#15112c86, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#3400f6a3, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#39669485, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#dfa43ef, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer#103a4d41, org.springframework.boot.test.context.SpringBootTestArgs#1, org.springframework.boot.test.context.SpringBootTestWebEnvironment#34fe2a08], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]
java.lang.IllegalStateException: Failed to retrieve PlatformTransactionManager for #Transactional test: [DefaultTestContext#39277750 testClass = ItemRepositoryTest, testInstance = com.ruckpack.equipmentservice.repository.ItemRepositoryTest#73bbbc73, testMethod = should test#ItemRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration#2c217989 testClass = ItemRepositoryTest, locations = '{}', classes = '{class com.ruckpack.equipmentservice.EquipmentServiceApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer#15112c86, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#3400f6a3, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#39669485, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#dfa43ef, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer#103a4d41, org.springframework.boot.test.context.SpringBootTestArgs#1, org.springframework.boot.test.context.SpringBootTestWebEnvironment#34fe2a08], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplication
Now this is my test class
#SpringBootTest
#Transactional
internal class ItemRepositoryTest #Autowired constructor(
private val itemRepository: ItemRepository
) {
#Test
fun `should test`() {
val expected = Item("001", "Meindl", "SuperBoot 300")
itemRepository.save(expected)
val actual = itemRepository.findById(expected.id)
assertThat(actual).isPresent
assertThat(actual.get()).isEqualTo(expected)
}
}
#Repository
interface ItemRepository: MongoRepository<Item, String>
Any my application class looks like this:
#SpringBootApplication
class EquipmentServiceApplication
fun main(args: Array<String>) {
runApplication<EquipmentServiceApplication>(*args)
}
I saw this tutorial: https://www.baeldung.com/spring-data-mongodb-transactions where the usage was done without any special configuration. That is why I am confused it does not work.
Here is my build.gradle.kt for completeness
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.4.2"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.4.30"
kotlin("plugin.spring") version "1.4.30"
}
group = "com.ruckpack"
version = "0.0.1"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
maven { url = uri("https://repo.spring.io/milestone") }
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("de.flapdoodle.embed:de.flapdoodle.embed.mongo")
testImplementation("org.springframework.security:spring-security-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
MongoDB versions 4 and above supports transactions. But are disabled by default in Spring Data MongoDB, you should define MongoTransactionManager explicitly.
Please read: https://docs.spring.io/spring-data/mongodb/docs/2.1.0.RC2/reference/html/#mongo.transactions
And
https://www.baeldung.com/spring-data-mongodb-transactions also says
"Note that we need to register MongoTransactionManager in our configuration to enable native MongoDB transactions as they are disabled by default."
Not sure about the syntax in Kotlin, for Java is:
#Bean
MongoTransactionManager txManager(MongoDbFactory mongoDbFactory) {
return new MongoTransactionManager(mongoDbFactory);
}
The Kolin version of the above would be something like:
#Bean
fun txManager(mongoDbFactory: MongoDbFactory) : MongoTransactionManager = MongoTransactionManager(mongoDbFactory)

Spring boot with testcontainers and jOOQ doesn't inject DSL context

I have some problem with spring boot + jOOQ and testcontainers. DSL context won't inject in my test class.
I made some preparations for using SQLContainer
class SpringTestContainer: PostgreSQLContainer<SpringTestContainer> {
private val postgreSqlPort = 5432
private val db = "m4"
companion object {
var instance: SpringTestContainer? = null
fun get(): SpringTestContainer {
if(instance == null) {
instance = SpringTestContainer()
}
return instance!!
}
}
override fun getDatabaseName(): String = db
constructor() : this("registry.dev.tskad.stdev.ru/m4/db:latest")
constructor(dockerImageName: String) : super(dockerImageName){
withImagePullPolicy(PullPolicy.alwaysPull())
addExposedPort(postgreSqlPort)
waitStrategy = LogMessageWaitStrategy()
.withRegEx(".*database system is ready to accept connections.*\\s")
.withTimes(1)
.withStartupTimeout(Duration.of(30, ChronoUnit.SECONDS))
}
override fun getJdbcUrl(): String {
return String.format("jdbc:postgresql://%s:%d/%s", containerIpAddress, getMappedPort(postgreSqlPort), databaseName)
}
override fun waitUntilContainerStarted() {
getWaitStrategy().waitUntilReady(this)
}
override fun getLivenessCheckPorts(): Set<Int?> {
return HashSet(getMappedPort(postgreSqlPort))
}
}
Then I created some abstraction for extending my integration test classes
#ContextConfiguration(initializers = [SpringIntegrationTest.Initializer::class])
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#JooqTest
abstract class SpringIntegrationTest {
#get:Rule
var postgreSQLContainer = SpringTestContainer.get()
inner class Initializer: ApplicationContextInitializer<ConfigurableApplicationContext> {
override fun initialize(applicationContext: ConfigurableApplicationContext) {
with(applicationContext.environment.systemProperties) {
put("spring.datasource.url", postgreSQLContainer.jdbcUrl)
put("spring.datasource.username", postgreSQLContainer.username)
put("spring.datasource.password", postgreSQLContainer.password)
}
}
}
}
and then I implemented test class
#ExtendWith(SpringExtension::class)
class TransactionRepositoryImplTest: SpringIntegrationTest() {
#Autowired
private var dslContext: DSLContext? = null
private var transactionRepository: TransactionRepository? = null
#Before
fun setUp() {
assertThat(dslContext).isNotNull
transactionRepository = TransactionRepositoryImpl(dslContext!!)
}
#After
fun tearDown() {
}
#Test
fun findTransactionData() {
transactionRepository?.findTransactionByVehicleUuid(null).apply {
assertNull(this)
}
}
}
and when I started tests of this class - tests are fails, because of assertions are not passed.
Here is the report of tests https://pastebin.com/0HeqDcCT
So.. how it impossible? I saw a few guides with this stack(Spring/jOOQ/TestContainers). And they are all working. Maybe I missed some test dependencies? If you have experience with this case - share your solution, please. I will be very grateful.
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.boot:spring-boot-starter-jooq")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.cloud:spring-cloud-starter-consul-config")
implementation("org.springframework.cloud:spring-cloud-stream")
implementation("org.springframework.cloud:spring-cloud-stream-binder-kafka")
implementation("org.springframework.kafka:spring-kafka")
implementation("org.springframework.boot:spring-boot-starter-amqp")
implementation ("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.3")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.10.3")
runtimeOnly("org.postgresql:postgresql:42.2.12")
jooqGeneratorRuntime("org.postgresql:postgresql:42.2.12")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
exclude(module = "junit")
}
testImplementation("com.ninja-squad:springmockk:2.0.1")
testImplementation("org.springframework.cloud:spring-cloud-stream-test-support")
testImplementation("org.springframework.kafka:spring-kafka-test")
testImplementation("org.springframework.amqp:spring-rabbit-test")
testImplementation("org.testcontainers:postgresql:1.14.3")
}
I might be missing something but in that setup, you have to manually run
postgreSQLContainer.start() somewhere. As an example it could be done in #BeforeAll.
I found the solution. The right way was to override the start method of test containers implementation and put in system properties the credentials to container DB.
Here is the working code:
class SpringTestContainer: PostgreSQLContainer<SpringTestContainer> {
private val postgreSqlPort = 5432
private val db = "m4"
companion object {
var instance: SpringTestContainer? = null
fun get(): SpringTestContainer {
if(instance == null) {
instance = SpringTestContainer()
}
return instance!!
}
}
override fun getDatabaseName(): String = db
constructor() : this("registry.dev.tskad.stdev.ru/m4/db:latest")
constructor(dockerImageName: String) : super(dockerImageName){
withImagePullPolicy(PullPolicy.alwaysPull())
addExposedPort(postgreSqlPort)
waitStrategy = LogMessageWaitStrategy()
.withRegEx(".*database system is ready to accept connections.*\\s")
.withTimes(1)
.withStartupTimeout(Duration.of(30, ChronoUnit.SECONDS))
}
override fun getJdbcUrl(): String {
return String.format("jdbc:postgresql://%s:%d/%s", containerIpAddress, getMappedPort(postgreSqlPort), databaseName)
}
override fun waitUntilContainerStarted() {
getWaitStrategy().waitUntilReady(this)
}
override fun getLivenessCheckPorts(): Set<Int?> {
return HashSet(getMappedPort(postgreSqlPort))
}
override fun start() {
super.start()
val container = get()
System.setProperty("DB_URL", container.jdbcUrl)
System.setProperty("DB_USERNAME", container.username)
System.setProperty("DB_PASSWORD", container.password)
}
}
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#SpringBootTest(properties = ["spring.cloud.consul.enabled = false"])
#EnableAutoConfiguration(exclude = [
RabbitAutoConfiguration::class,
KafkaAutoConfiguration::class
])
class TransactionRepositoryImplTest {
#get:Rule
var postgreSQLContainer = SpringTestContainer.get()
#Autowired
private lateinit var dslContext: DSLContext
#Autowired
private lateinit var transactionRepository: TransactionRepository
#MockkBean
private lateinit var connectionFactory: ConnectionFactory // this is the mock for rabbit connection. U may ignore it.
#Test
fun contextLoads() {
Assertions.assertNotNull(dslContext)
Assertions.assertNotNull(transactionRepository)
}
}
and then need to fix application.yml in the tests directory
spring:
datasource:
platform: postgres
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
driverClassName: org.postgresql.Driver
in java it helps me:
on test put annotation. See JooqAutoConfiguration.class
#Import({ DataSourceAutoConfiguration.class,
TransactionAutoConfiguration.class, JooqAutoConfiguration.class})

when using JpaRepository o.h.i.SessionFactoryImpl : HHH000031: Closing

I have a problem when starting spring-boot appication with Using JpaRepository.
more details, deleting findReviewByUser_num inside ReviewRepository works well.
My code did not have a Controller, Service, and I was creating Repository and just testing.
Review.Java
package org.soma.tripper.review.entity;
import lombok.*;
import javax.persistence.*;
import java.util.List;
#Getter
#Entity
#NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Review {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int review_num;
#Column(name = "user_num")
private int user_num;
#Column(name = "schedule_num")
private String schedule_num;
#Column(name = "content",length = 1000)
private String content;
#Column(name="rating")
private double rating;
#Column(name="ml_rating")
private double ml_rating;
#Builder Review(int user_num, int schedule_num, String content, double rating){
this.user_num=user_num;
this.user_num = schedule_num;
this.content=content;
this.rating = rating;
}
}
ReviewRepository.java
package org.soma.tripper.review.repository;
import org.soma.tripper.review.entity.Review;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ReviewRepository extends JpaRepository<Review,Integer> {
Review findReviewByUser_num(int user_num);
}
build.gradle
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
jar {
manifest {
attributes 'Main-Class': 'org.soma.tripper.TripperApplication'
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
group = 'org.soma'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
//swagger
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.5.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.5.0'
//jpa
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compileOnly('org.projectlombok:lombok')
//logback
compile('ch.qos.logback:logback-classic:1.2.3')
compile('ch.qos.logback:logback-core:1.2.3')
compile 'log4j:log4j:1.2.17'
compile 'org.slf4j:slf4j-api:1.7.5'
compile 'org.slf4j:slf4j-log4j12:1.7.5'
// S3
// https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk
compile group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.11.371'
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.6'
compile('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
console

Querydsl - IntelliJ and code generation

I have a Spring Boot Gradle project using Spring Data MongoDB.
In order to generate the query type classes, I have to run the gradle build task.
Is there a way for creating the query type classes when saving the file in IntelliJ? I have already enabled annotation processing in the project.
I would like to have a behavior like the lombok plugin, where it is not needed to build the project to see the changes.
Below is my build.gradle file:
buildscript {
ext {
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.franzbecker:gradle-lombok:1.11")
classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.9")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: "io.franzbecker.gradle-lombok"
apply plugin: "com.ewerk.gradle.plugins.querydsl"
group = 'com.henrique'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile("com.querydsl:querydsl-mongodb:4.1.4")
compileOnly("com.querydsl:querydsl-apt:4.1.4")
testCompile('org.springframework.boot:spring-boot-starter-test')
}
querydsl {
springDataMongo = true
querydslSourcesDir = "$buildDir/generated/source/app/main"
}
sourceSets {
main {
java {
srcDir "$buildDir/generated/source/app/main"
}
}
}
Here is my domain entity:
#Data
#Builder
#Document
public class Customer {
#Id
private String id;
private String firstName;
private String lastName;
private String zipCode;
}
And here is the query type generated:
#Generated("com.querydsl.codegen.EntitySerializer")
public class QCustomer extends EntityPathBase<Customer> {
private static final long serialVersionUID = -1386833698L;
public static final QCustomer customer = new QCustomer("customer");
public final StringPath firstName = createString("firstName");
public final StringPath id = createString("id");
public final StringPath lastName = createString("lastName");
public final StringPath zipCode = createString("zipCode");
public QCustomer(String variable) {
super(Customer.class, forVariable(variable));
}
public QCustomer(Path<? extends Customer> path) {
super(path.getType(), path.getMetadata());
}
public QCustomer(PathMetadata metadata) {
super(Customer.class, metadata);
}
}

Resources