Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: silently ignores exception when parameter setting to count query #781

Merged
merged 9 commits into from
Oct 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package com.linecorp.kotlinjdsl.support.spring.data.jpa.javax

import com.linecorp.kotlinjdsl.querymodel.jpql.JpqlQuery
import com.linecorp.kotlinjdsl.render.RenderContext
import org.slf4j.LoggerFactory
import org.springframework.data.domain.Sort
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import javax.persistence.EntityManager
Expand Down Expand Up @@ -97,8 +98,20 @@ internal object JpqlEntityManagerUtils {
}

private fun setParams(query: Query, params: Map<String, Any?>) {
shouwn marked this conversation as resolved.
Show resolved Hide resolved
val parameterList = query.parameters.map { it.name }.toHashSet()

params.forEach { (name, value) ->
query.setParameter(name, value)
if (parameterList.contains(name)) {
query.setParameter(name, value)
} else {
log.debug(
"No parameter named '{}' in query with named parameters [{}], parameter binding skipped",
name,
parameterList.joinToString(),
)
}
}
}
}

private val log = LoggerFactory.getLogger(JpqlEntityManagerUtils::class.java)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.springframework.data.domain.Sort
import org.springframework.data.jpa.repository.query.QueryEnhancer
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import javax.persistence.EntityManager
import javax.persistence.Parameter
import javax.persistence.TypedQuery

@ExtendWith(MockKExtension::class)
Expand All @@ -41,9 +42,21 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@MockK
private lateinit var stringTypedQuery1: TypedQuery<String>

@MockK
private lateinit var stringTypedQueryParam1: Parameter<String>

@MockK
private lateinit var stringTypedQueryParam2: Parameter<String>

@MockK
private lateinit var longTypedQuery1: TypedQuery<Long>

@MockK
private lateinit var longTypedQueryParam1: Parameter<String>

@MockK
private lateinit var longTypedQueryParam2: Parameter<String>

private val sort1 = Sort.by("property1")

private val renderedQuery1 = "query"
Expand All @@ -67,6 +80,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
excludeRecords { JpqlRendererHolder.get() }
excludeRecords { stringTypedQuery1.equals(any()) }
excludeRecords { longTypedQuery1.equals(any()) }
excludeRecords { longTypedQueryParam1.hashCode() }
excludeRecords { longTypedQueryParam2.hashCode() }
excludeRecords { stringTypedQueryParam1.hashCode() }
excludeRecords { stringTypedQueryParam2.hashCode() }
}

@Test
Expand All @@ -76,7 +93,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>(), any<Class<String>>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils.createQuery(entityManager, query1, String::class, context)
Expand All @@ -87,6 +107,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, context)
entityManager.createQuery(rendered1.query, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -99,7 +122,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>(), any<Class<String>>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -111,6 +137,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, mapOf(queryParam1, queryParam2), context)
entityManager.createQuery(rendered1.query, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -123,7 +152,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils.createQuery(entityManager, query1, context)
Expand All @@ -134,6 +166,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, context)
entityManager.createQuery(rendered1.query)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -146,7 +181,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -158,6 +196,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, mapOf(queryParam1, queryParam2), context)
entityManager.createQuery(rendered1.query)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -175,8 +216,14 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
every {
entityManager.createQuery(any<String>(), any<Class<*>>())
} returns stringTypedQuery1 andThen longTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first
every { longTypedQuery1.parameters } returns setOf(longTypedQueryParam1, longTypedQueryParam2)
every { longTypedQuery1.setParameter(any<String>(), any()) } returns longTypedQuery1
every { longTypedQueryParam1.name } returns renderedParam1.first
every { longTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -193,11 +240,17 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

queryEnhancer.applySorting(sort1)
entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)

queryEnhancer.createCountQueryFor()
entityManager.createQuery(countQuery1, Long::class.javaObjectType)
longTypedQuery1.parameters
longTypedQueryParam1.name
longTypedQueryParam2.name
longTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
longTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.linecorp.kotlinjdsl.render.RenderContext
import jakarta.persistence.EntityManager
import jakarta.persistence.Query
import jakarta.persistence.TypedQuery
import org.slf4j.LoggerFactory
import org.springframework.data.domain.Sort
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import kotlin.reflect.KClass
Expand Down Expand Up @@ -97,8 +98,20 @@ internal object JpqlEntityManagerUtils {
}

private fun setParams(query: Query, params: Map<String, Any?>) {
val parameterList = query.parameters.map { it.name }.toHashSet()

params.forEach { (name, value) ->
query.setParameter(name, value)
if (parameterList.contains(name)) {
query.setParameter(name, value)
} else {
log.debug(
"No parameter named '{}' in query with named parameters [{}], parameter binding skipped",
name,
parameterList.joinToString(),
)
}
}
}
}

private val log = LoggerFactory.getLogger(JpqlEntityManagerUtils::class.java)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.mockk.junit5.MockKExtension
import io.mockk.mockkObject
import io.mockk.verifySequence
import jakarta.persistence.EntityManager
import jakarta.persistence.Parameter
import jakarta.persistence.TypedQuery
import org.assertj.core.api.WithAssertions
import org.junit.jupiter.api.BeforeEach
Expand Down Expand Up @@ -41,9 +42,21 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@MockK
private lateinit var stringTypedQuery1: TypedQuery<String>

@MockK
private lateinit var stringTypedQueryParam1: Parameter<String>

@MockK
private lateinit var stringTypedQueryParam2: Parameter<String>

@MockK
private lateinit var longTypedQuery1: TypedQuery<Long>

@MockK
private lateinit var longTypedQueryParam1: Parameter<String>

@MockK
private lateinit var longTypedQueryParam2: Parameter<String>

private val sort1 = Sort.by("property1")

private val renderedQuery1 = "query"
Expand All @@ -67,6 +80,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
excludeRecords { JpqlRendererHolder.get() }
excludeRecords { stringTypedQuery1.equals(any()) }
excludeRecords { longTypedQuery1.equals(any()) }
excludeRecords { longTypedQueryParam1.hashCode() }
excludeRecords { longTypedQueryParam2.hashCode() }
excludeRecords { stringTypedQueryParam1.hashCode() }
excludeRecords { stringTypedQueryParam2.hashCode() }
}

@Test
Expand All @@ -76,7 +93,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>(), any<Class<String>>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils.createQuery(entityManager, query1, String::class, context)
Expand All @@ -87,6 +107,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, context)
entityManager.createQuery(rendered1.query, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -99,7 +122,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>(), any<Class<String>>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -111,6 +137,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, mapOf(queryParam1, queryParam2), context)
entityManager.createQuery(rendered1.query, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -123,7 +152,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils.createQuery(entityManager, query1, context)
Expand All @@ -134,6 +166,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, context)
entityManager.createQuery(rendered1.query)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -146,7 +181,10 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any(), any()) } returns rendered1
every { entityManager.createQuery(any<String>()) } returns stringTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -158,6 +196,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
verifySequence {
renderer.render(query1, mapOf(queryParam1, queryParam2), context)
entityManager.createQuery(rendered1.query)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand All @@ -175,8 +216,14 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
every {
entityManager.createQuery(any<String>(), any<Class<*>>())
} returns stringTypedQuery1 andThen longTypedQuery1
every { stringTypedQuery1.parameters } returns setOf(stringTypedQueryParam1, stringTypedQueryParam2)
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQueryParam1.name } returns renderedParam1.first
every { stringTypedQueryParam2.name } returns renderedParam2.first
every { longTypedQuery1.parameters } returns setOf(longTypedQueryParam1, longTypedQueryParam2)
every { longTypedQuery1.setParameter(any<String>(), any()) } returns longTypedQuery1
every { longTypedQueryParam1.name } returns renderedParam1.first
every { longTypedQueryParam2.name } returns renderedParam2.first

// when
val actual = JpqlEntityManagerUtils
Expand All @@ -193,11 +240,17 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

queryEnhancer.applySorting(sort1)
entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.parameters
stringTypedQueryParam1.name
stringTypedQueryParam2.name
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
stringTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)

queryEnhancer.createCountQueryFor()
entityManager.createQuery(countQuery1, Long::class.javaObjectType)
longTypedQuery1.parameters
longTypedQueryParam1.name
longTypedQueryParam2.name
longTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
longTypedQuery1.setParameter(renderedParam2.first, renderedParam2.second)
}
Expand Down