0

Relevant information: I am using Kotlin and Hibernate and gradle.

Maybe relevant information: I am not using Spring at all. I am using Micronaut-Data

Issue:

When I try a simple get

curl --location --request GET 'localhost:8080/accountholders?id=1'

I get

[default-nioEventLoopGroup-1-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: org.hibernate.InstantiationException: No default constructor for entity:  : com.mybank.model.AccountHolder
javax.persistence.PersistenceException: org.hibernate.InstantiationException: No default constructor for entity:  : com.mybank.model.AccountHolder
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1542)
    at org.hibernate.query.internal.AbstractProducedQuery.uniqueResult(AbstractProducedQuery.java:1575)
    at org.hibernate.query.internal.AbstractProducedQuery.uniqueResultOptional(AbstractProducedQuery.java:1526)
    at io.micronaut.data.hibernate.operations.HibernateJpaOperations.lambda$findOne$2(HibernateJpaOperations.java:173)
    at io.micronaut.transaction.support.AbstractSynchronousTransactionManager.executeRead(AbstractSynchronousTransactionManager.java:155)
...
Caused by: org.hibernate.InstantiationException: No default constructor for entity:  : com.mybank.model.AccountHolder
    at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:85)

Searching around I read from kotlin reference about no-arg-compiler-plugin. So I added but I didn't see any change at all. Probably there is an extra step exemplify by

noArg {
    annotation("com.my.Annotation")
}

and

noArg {
    invokeInitializers = true
}

Please, can someone take a look at my build.gradle and entity tell me what I am missing so far?

build.gradle

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.4.10"
    id "org.jetbrains.kotlin.kapt" version "1.4.10"
    id "org.jetbrains.kotlin.plugin.allopen" version "1.4.10"
    id "com.github.johnrengelman.shadow" version "6.1.0"
    id "io.micronaut.application" version '1.0.5'
    id "org.jetbrains.kotlin.plugin.noarg" version "1.4.10"
}

noArg {
    annotation("com.my.Annotation")
}

version "0.1"
group "com.mybank"

repositories {
    mavenCentral()
    jcenter()
}

micronaut {
    runtime "netty"
    testRuntime "junit5"
    processing {
        incremental true
        annotations "com.mybank.*"
    }
}

dependencies {
    kapt("io.micronaut.data:micronaut-data-processor")
    implementation("io.micronaut:micronaut-validation")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
    implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
    implementation("io.micronaut:micronaut-runtime")
    implementation("javax.annotation:javax.annotation-api")
    implementation("io.micronaut:micronaut-http-client")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
    runtimeOnly("ch.qos.logback:logback-classic")
    runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
    runtimeOnly("com.h2database:h2")
}

mainClassName = "com.mybank.ApplicationKt"
java {
    sourceCompatibility = JavaVersion.toVersion('11')
}

compileKotlin {
    kotlinOptions {
        jvmTarget = '11'
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = '11'
    }
}

Enitities:

import javax.persistence.*
    
        @Entity
        @Table(name = "accounts")
        data class Account(@Id
                           //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "account_generator")
                           //@SequenceGenerator(name = "account_generator", sequenceName = "account_seq")
                           @Column(name="ID_ACCOUNT", nullable=false)
                           //@GeneratedValue(strategy=GenerationType.SEQUENCE)
                           @GeneratedValue(strategy=GenerationType.IDENTITY)
                           var accountId: Long,
                           var name: String? = null,
        
        
                           @ManyToOne(fetch = FetchType.LAZY, optional = true)
                           @JoinColumn(name = "ACCOUNTHOLDER_ID", nullable=true, insertable=false, updatable=false)
                           val accountHolder: AccountHolder
        
        )

and

import com.fasterxml.jackson.annotation.JsonFormat
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import java.time.LocalDate
import javax.persistence.*


@Entity
data class AccountHolder(@Id
                         //@GeneratedValue //(strategy = GenerationType.SEQUENCE, generator = "account_generator")
                         //@SequenceGenerator(name="account_generator", sequenceName = "account_seq")
                         @Column(name="accountHolderId", nullable=false)
                         //@GeneratedValue(strategy=GenerationType.SEQUENCE)
                         @GeneratedValue(strategy=GenerationType.IDENTITY)
                         var accountHolderId: Long,
                         var name: String? = null,
                         var age: Int,
                         @field:JsonFormat(pattern = "yyyy-MM-dd")
                         @field:JsonSerialize(using = LocalDateSerializer::class)
                         @field:JsonDeserialize(using = LocalDateDeserializer::class)
                         var birthDate: LocalDate,
                         var category: Category,
                         @Column(nullable = true)
                         @OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, mappedBy = "accountId")
                         val account: List<Account>? = null

)

repositories:

import com.mybank.model.AccountHolder
import io.micronaut.data.repository.CrudRepository
import io.micronaut.context.annotation.Executable
import io.micronaut.data.annotation.*

@Repository
interface AccountHolderRepository: CrudRepository<AccountHolder, Long> {
    @Executable
    fun find(name: String): AccountHolder
}

and

import com.mybank.model.Account
import io.micronaut.data.annotation.Repository
import io.micronaut.data.repository.CrudRepository

@Repository
interface AccountRepository : CrudRepository<Account, Long> {
}

controllers:

import com.mybank.model.Account
import com.mybank.service.AccountService
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.*

@Controller("/accounts")
class AccountController(private val accountService: AccountService)
{

    @Post
    @Consumes(MediaType.APPLICATION_JSON)
    fun addAccount(@Body account: Account): Account {
        return accountService.addAccount(account)
    }

    @Get
    fun getAccount(id: Long): Account {
        return accountService.findAccountById(id)
    }
}

and

import com.mybank.model.AccountHolder
import com.mybank.service.AccountHolderService
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.*

@Controller("/accountholders")
class AccountHolderController(private val accountHolderService: AccountHolderService) {

    @Post
    @Consumes(MediaType.APPLICATION_JSON)
    fun addAccountHolder(@Body accountHolder: AccountHolder): AccountHolder {
        return accountHolderService.addAccountHolder(accountHolder)
    }

    @Get
    fun getAccountHolder(id: Long): AccountHolder{
        return accountHolderService.findAccountHolderById(id)
    }
}

Whole project can fe found in git hub master branch

*** edited after Jeff suggestion

build.gradle

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.4.10"
    id "org.jetbrains.kotlin.kapt" version "1.4.10"
    id "org.jetbrains.kotlin.plugin.allopen" version "1.4.10"
    id "com.github.johnrengelman.shadow" version "6.1.0"
    id "io.micronaut.application" version '1.0.5'
    id "org.jetbrains.kotlin.plugin.noarg" version "1.4.10"
}

noArg {
    annotation("com.my.Annotation")
}

version "0.1"
group "com.mybank"

repositories {
    mavenCentral()
    jcenter()
}

micronaut {
    runtime "netty"
    testRuntime "junit5"
    processing {
        incremental true
        annotations "com.mybank.*"
    }
}

dependencies {
    kapt("io.micronaut.data:micronaut-data-processor")
    implementation("io.micronaut:micronaut-validation")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
    implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
    implementation("io.micronaut:micronaut-runtime")
    implementation("javax.annotation:javax.annotation-api")
    implementation("io.micronaut:micronaut-http-client")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    implementation("io.micronaut.data:micronaut-data-hibernate-jpa")
    runtimeOnly("ch.qos.logback:logback-classic")
    runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
    runtimeOnly("com.h2database:h2")

}

mainClassName = "com.mybank.ApplicationKt"
java {
    sourceCompatibility = JavaVersion.toVersion('11')
}

compileKotlin {
    kotlinOptions {
        jvmTarget = '11'
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = '11'
    }
}

apply plugin: "kotlin-noarg"

noArg {
    annotation("com.mybank.model.NoArg")
    invokeInitializers = true
}

NoArg class

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class NoArg

Entity

@Entity
@Table(name = "accounts")
@NoArg
data class Account(@Id

credits also to other answer but I understand the question topic is complete different than mine: I clearly asked about kotlin-noarg that was failling the way I was using while in this question the peerson asked "How to create empty constructor for data class in Kotlin Android"

Jim C
  • 2,519
  • 13
  • 54
  • 105
  • 1
    Does this answer your question? [How to create empty constructor for data class in Kotlin Android](https://stackoverflow.com/questions/37873995/how-to-create-empty-constructor-for-data-class-in-kotlin-android) – Jeff Scott Brown Nov 11 '20 at 14:31
  • thanks. It is working now. I added above what fix my issue. A last help with gradle if you don't mind: I couldn't add classpath "org.jetbrains.kotlin:kotlin-noarg:1.4.10" under my dependencies Is id "org.jetbrains.kotlin.plugin.noarg" version "1.4.10" under plugins equivalent to classpath under dependencies? Honestly, a bit strange it is working since I didn't add kotlin-norg inside dependencies – Jim C Nov 11 '20 at 15:55
  • 1
    `"I couldn't add classpath "org.jetbrains.kotlin:kotlin-noarg:1.4.10" under my dependencies"` - Why not? What happens if you add `compile 'org.jetbrains.kotlin:kotlin-noarg:1.4.10'`? – Jeff Scott Brown Nov 11 '20 at 16:39
  • I mean, classpath "org.." instead of compile "org...". Well, all examples I saw so far was using classpath "org..:kotlin-noarg:1.4.10". If you don't mind, what is the difference between I add id "org.jetbrains.kotlin.plugin.noarg" version "1.4.10" inside plugins and I add inside dependencies ? (see my build.gradle above to understand what I mean by plugins{} and dependencies{}. – Jim C Nov 11 '20 at 18:02
  • 1
    `I mean, classpath "org.." instead of compile "org..."` - I don't know what that means. `what is the difference between I add id "org.jetbrains.kotlin.plugin.noarg" version "1.4.10" inside plugins and I add inside dependencies` - The former is for dependencies needed by the Gradle build and the latter is for dependencies needed by your application. – Jeff Scott Brown Nov 11 '20 at 18:10
  • 1
    Upon re-reading your question, I may realize now what you mean by the difference between `classpath ...` and `id ...`. If I understand the question, the `classpath ...` entry is adding the library to the classpath and the `id ...` entry is installing the plugin. – Jeff Scott Brown Nov 11 '20 at 19:54
  • 1
    https://kotlinlang.org/docs/reference/compiler-plugins.html#no-arg-compiler-plugin explains how that works. – Jeff Scott Brown Nov 11 '20 at 19:54

0 Answers0