After 3.2.0 update, the querydsl embedded column type comparison operation is not possible.
In version 3.1.4, it worked without any problems, but the equals operation for embedded columns does not work properly after the 3.2.0 update.
Currently operating based on kotlin - JVM17.
The error code is as follows.
java.lang.IllegalArgumentException: org.hibernate.query.SemanticException: Cannot compare tuples of different lengths
at org.hibernate.internal.ExceptionConverterImpl.convert(exceptionconverterimpl.java:143)
at org.hibernate.internal.ExceptionConverterImpl.convert(exceptionconverterimpl.java:167)
at org.hibernate.internal.ExceptionConverterImpl.convert(exceptionconverterimpl.java:173)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(abstractsharedsessioncontract.java:802)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(abstractsharedsessioncontract.java:707)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(abstractsharedsessioncontract.java:132)
at java.base/java.lang.reflect.Method.invoke(method.java:568)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(sharedentitymanagercreator.java:311)
at jdk.proxy2/jdk.proxy2.$Proxy233.createQuery(Unknown Source)
at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(abstractjpaquery.java:132)
at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(abstractjpaquery.java:125)
at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(abstractjpaquery.java:242)
at site.qbox.qboxserver.domain.question.query.QuestionDao.findAllBy(QuestionDao.kt:26)
at java.base/java.lang.reflect.Method.invoke(method.java:568)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(aoputils.java:352)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(reflectivemethodinvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(reflectivemethodinvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(cglibaopproxy.java:765)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(transactioninterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(transactionaspectsupport.java:385)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(transactioninterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(reflectivemethodinvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(cglibaopproxy.java:765)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(cglibaopproxy.java:717)
at site.qbox.qboxserver.domain.question.query.QuestionDao$$SpringCGLIB$$0.findAllBy(<generated>)
at site.qbox.qboxserver.domain.question.query.QuestionDaoTest$1$2.invokeSuspend(QuestionDaoTest.kt:58)
at site.qbox.qboxserver.domain.question.query.QuestionDaoTest$1$2.invoke(QuestionDaoTest.kt)
at site.qbox.qboxserver.domain.question.query.QuestionDaoTest$1$2.invoke(QuestionDaoTest.kt)
at io.kotest.core.spec.style.scopes.DescribeSpecContainerScope$it$3.invokeSuspend(DescribeSpecContainerScope.kt:113)
at io.kotest.core.spec.style.scopes.DescribeSpecContainerScope$it$3.invoke(DescribeSpecContainerScope.kt)
at io.kotest.core.spec.style.scopes.DescribeSpecContainerScope$it$3.invoke(DescribeSpecContainerScope.kt)
at io.kotest.engine.test.TestCaseExecutor$execute$innerExecute$1.invokeSuspend(TestCaseExecutor.kt:88)
at io.kotest.engine.test.TestCaseExecutor$execute$innerExecute$1.invoke(TestCaseExecutor.kt)
at io.kotest.engine.test.TestCaseExecutor$execute$innerExecute$1.invoke(TestCaseExecutor.kt)
at io.kotest.engine.test.interceptors.CoroutineDebugProbeInterceptor.intercept(CoroutineDebugProbeInterceptor.kt:29)
at io.kotest.engine.test.TestCaseExecutor$execute$3$1.invokeSuspend(TestCaseExecutor.kt:97)
at io.kotest.engine.test.TestCaseExecutor$execute$3$1.invoke(TestCaseExecutor.kt)
at io.kotest.engine.test.TestCaseExecutor$execute$3$1.invoke(TestCaseExecutor.kt)
....mores
Build.gradle.kts is as follows.
plugins {
id("org.springframework.boot") version "3.2.0"
id("io.spring.dependency-management") version "1.1.4"
id("org.jetbrains.kotlinx.kover") version "0.7.3"
id("org.asciidoctor.jvm.convert") version "3.3.2"
kotlin("jvm") version "1.9.20"
kotlin("plugin.spring") version "1.9.20"
kotlin("plugin.jpa") version "1.9.20"
kotlin("kapt") version "1.9.20"
}
group = "site.q-box"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
extra["snippetsDir"] = file("build/generated-snippets")
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-mail")
implementation("com.github.maricn:logback-slack-appender:1.6.1")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-data-redis")
testImplementation("org.springframework.boot:spring-boot-starter-test")
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
//kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
//database
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("com.mysql:mysql-connector-j")
testRuntimeOnly("com.h2database:h2")
//querydsl
implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta")
kapt("com.querydsl:querydsl-apt:5.0.0:jakarta")
//security
implementation("org.springframework.boot:spring-boot-starter-security")
testImplementation("org.springframework.security:spring-security-test")
//test container
testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("com.redis.testcontainers:testcontainers-redis-junit:1.6.4")
//monitoring
implementation("org.springframework.boot:spring-boot-starter-actuator")
runtimeOnly("io.micrometer:micrometer-registry-prometheus")
// rest docs
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
testImplementation("org.springframework.restdocs:spring-restdocs-asciidoctor")
//kotest
testImplementation("io.kotest:kotest-runner-junit5:5.6.2")
testImplementation("io.kotest:kotest-assertions-core:5.6.2")
testImplementation("io.kotest.extensions:kotest-extensions-spring:1.1.3")
//mockkk
testImplementation("io.mockk:mockk:1.13.8")
testImplementation("com.ninja-squad:springmockk:4.0.2")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
//docs setting
tasks {
val snippetsDir = file("$buildDir/generated-snippets")
clean {
delete("src/main/resources/static/docs")
}
test {
useJUnitPlatform()
systemProperty("org.springframework.restdocs.outputDir", snippetsDir)
outputs.dir(snippetsDir)
}
asciidoctor {
dependsOn(test)
attributes(
mapOf("snippets" to snippetsDir)
)
inputs.dir(snippetsDir)
doFirst {
delete("src/main/resources/static/docs")
}
}
register<Copy>("copyDocument") {
dependsOn(asciidoctor)
destinationDir = file(".")
from(asciidoctor.get().outputDir) {
into("src/main/resources/static/docs")
}
}
bootJar {
dependsOn(asciidoctor)
from(asciidoctor.get().outputDir) {
into("BOOT-INF/classes/static/docs")
}
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3")
}
}
kover {
excludeJavaCode()
}
The example entity code is as follows.
@Entity
class Question(
@Column(nullable = false) var title: String,
@Lob @Column(nullable = false) var body: String,
@Embedded val lecture: LectureId,
@Column(nullable = false) val writerId: String,
@Id @GeneratedValue val id: Long = 0L,
) : BaseEntity() {
fun changeContents(title: String, body: String) {
this.title = title
this.body = body
}
}
@Embeddable
data class LectureId(
val code: String,
val departId: Long
) : Serializable
Comment From: wilkinsona
This is almost certainly a Hibernate issue. Please try Spring Boot 3.1.x upgraded to Hibernate 6.3.2.Final to see if the problem occurs. You may also want to try Spring Boot 3.2.0 with Hibernate 6.4.0.Final to see if they've already fixed the problem (there is some similarity with HHH-17454).