Reputation: 970
I have a Kotlin SpringBoot project. It's a relatively simple API that persists data to a Postgres JsonB database.
I am using the @TypeDef
annotation on my entity class, but after upgrading to SpringBoot Version 3.0
with hibernate-core:6.1.7.Final
this annotation is no longer available.
Here is my entity class::
import com.vladmihalcea.hibernate.type.json.JsonBinaryType
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Id
import jakarta.persistence.Table
import org.hibernate.annotations.Type
import org.hibernate.annotations.TypeDef // not available with latest hibernate-core
import java.io.Serializable
import java.security.SecureRandom
import kotlin.math.abs
@Entity
@Table(name = "myTable")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType::class) // not available :(
data class RecommendationEntity(
@Id
open var id: Long = abs(SecureRandom().nextInt().toLong()),
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
var data: MyModel
)
data class MyModel(
// nothing special just a POJO
) : Serializable
And here is my build.gradle.kts::
plugins {
id("XXXXXXXXXX.gradle-spring-boot") version "5.0.1" // in house plugin thatcopies 3.0.2
kotlin("jvm") version "1.8.10"
kotlin("plugin.jpa") version "1.8.20-Beta"
kotlin("plugin.spring") version "1.8.20-Beta"
}
jacoco.toolVersion = "0.8.8"
configurations {
testImplementation { exclude(group = "org.junit.vintage") }
}
testSets {
"testSmoke"()
}
// allOpen {
// annotations("javax.persistence.Entity")
// }
val springDocVersion = "1.6.14"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-actuator:3.0.1")
implementation("com.deepoove:poi-tl:1.12.1") {
// exclude apache.xmlgraphics batik due to vulnerabilities when imported with poi-tl
exclude("org.apache.xmlgraphics", "batik-codec")
exclude("org.apache.xmlgraphics", "batik-transcoder")
}
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.flywaydb:flyway-core:9.11.0")
implementation("org.postgresql:postgresql:42.5.1")
implementation("org.springdoc:springdoc-openapi-webmvc-core:$springDocVersion")
implementation("org.springdoc:springdoc-openapi-ui:$springDocVersion")
implementation("org.springdoc:springdoc-openapi-kotlin:$springDocVersion")
implementation("org.springdoc:springdoc-openapi-data-rest:$springDocVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.7.0")
implementation("com.vladmihalcea:hibernate-types-52:2.21.1")
// implementation("org.hibernate:hibernate-core:5.6.3.Final")
// https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core
implementation("org.hibernate.orm:hibernate-core:6.1.7.Final")
testImplementation("org.awaitility:awaitility-kotlin:4.2.0")
testImplementation("org.mock-server:mockserver-netty:5.15.0")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("io.jsonwebtoken:jjwt:0.9.1")
testImplementation("com.natpryce:hamkrest:1.8.0.1")
testImplementation("org.flywaydb.flyway-test-extensions:flyway-spring-test:7.0.0")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(18))
}
}
tasks {
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "18"
}
}
}
tasks.test {
finalizedBy(tasks.jacocoTestReport)
}
tasks.jacocoTestReport {
dependsOn(tasks.test)
reports {
xml.required.set(true)
}
}
val SourceSet.kotlin: SourceDirectorySet
get() = project.extensions.getByType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension>().sourceSets.getByName(
name
).kotlin
sourceSets {
create("functional-test") {
kotlin.srcDirs("src/functional-test")
compileClasspath += sourceSets["main"].output + configurations["testRuntimeClasspath"]
runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath
}
}
tasks.withType<Jar>() {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
What I've tried::
@TypeDef
is available, but that gives the error -Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Class org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider does not implement the requested interface jakarta.persistence.spi.PersistenceProvider
SpringBoot V3.0
I'm quite stumped on this one, and am beginning to think that SpringBoot V3.0
doesn't support Postgres JsonB Nosql :(
Can anybody help me with a solution? Or perhaps confirm whether Postgres JsonB Nosql is indeed not supported in the new SpringBoot
version?
Thanks
Upvotes: 3
Views: 7775
Reputation: 970
I found the solution here - https://github.com/vladmihalcea/hypersistence-utils/issues/367#issuecomment-1398737096
I bumped the version of my hibernate-types
dependency implementation("com.vladmihalcea:hibernate-types-60:2.21.1")
And made changes to my entity class as recommended -
@Entity
@Table(name = "myTable")
// @TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
data class MyEntity(
@Id
open var id: Long = abs(SecureRandom().nextInt().toLong()),
// @Type(type = "jsonb")
// @Column(columnDefinition = "jsonb")
@Type(JsonType::class)
@Column(columnDefinition = "jsonb")
var data: MyModel
)
And now the issue is gone!
Upvotes: 12