Skip to content

Commit

Permalink
Merge pull request #631 from line/feature/query-enhancer-for-pageable
Browse files Browse the repository at this point in the history
fix: support a fetch join in the spring page query
  • Loading branch information
cj848 authored Feb 8, 2024
2 parents c6282e9 + 5bada5d commit a6d474b
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.data.domain.SliceImpl
import org.springframework.data.jpa.repository.query.QueryUtilsAdaptor
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import org.springframework.data.support.PageableExecutionUtilsAdaptor
import javax.persistence.EntityManager
import javax.persistence.Query
Expand Down Expand Up @@ -141,7 +141,9 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): List<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)

val jpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand All @@ -161,8 +163,10 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): Page<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val countQuery = QueryUtilsAdaptor.createCountQueryFor(rendered.query, null, false)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)
val countQuery = queryEnhancer.createCountQueryFor()

val sortedJpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand Down Expand Up @@ -194,7 +198,9 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): Slice<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)

val jpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.springframework.data.jpa.repository.query

internal object QueryEnhancerFactoryAdaptor {
fun forQuery(query: String): QueryEnhancer {
return QueryEnhancerFactory.forQuery(StringQuery(query, false))
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.SliceImpl
import org.springframework.data.jpa.repository.query.QueryUtilsAdaptor
import org.springframework.data.jpa.repository.query.QueryEnhancer
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import org.springframework.data.support.PageableExecutionUtilsAdaptor
import java.util.function.LongSupplier
import javax.persistence.EntityManager
Expand All @@ -37,6 +38,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@MockK
private lateinit var context: RenderContext

@MockK
private lateinit var queryEnhancer: QueryEnhancer

@MockK
private lateinit var selectQuery1: SelectQuery<String>

Expand Down Expand Up @@ -69,7 +73,7 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@Suppress("UnusedEquals")
fun setUp() {
mockkObject(JpqlRendererHolder)
mockkObject(QueryUtilsAdaptor)
mockkObject(QueryEnhancerFactoryAdaptor)
mockkObject(PageableExecutionUtilsAdaptor)

every { JpqlRendererHolder.get() } returns renderer
Expand Down Expand Up @@ -233,7 +237,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { entityManager.createQuery(any<String>(), any<Class<*>>()) } returns stringTypedQuery1
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQuery1.setFirstResult(any()) } returns stringTypedQuery1
Expand All @@ -250,7 +255,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand All @@ -273,8 +279,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryUtilsAdaptor.createCountQueryFor(any(), any(), any()) } returns countQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { queryEnhancer.createCountQueryFor() } returns countQuery1
every {
entityManager.createQuery(any<String>(), any<Class<*>>())
} returns stringTypedQuery1 andThen longTypedQuery1
Expand All @@ -300,8 +307,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryUtilsAdaptor.createCountQueryFor(rendered1.query, null, false)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)
queryEnhancer.createCountQueryFor()

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand Down Expand Up @@ -329,7 +337,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { entityManager.createQuery(any<String>(), any<Class<*>>()) } returns stringTypedQuery1
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQuery1.setFirstResult(any()) } returns stringTypedQuery1
Expand All @@ -346,7 +355,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.data.domain.SliceImpl
import org.springframework.data.jpa.repository.query.QueryUtilsAdaptor
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import org.springframework.data.support.PageableExecutionUtilsAdaptor
import kotlin.reflect.KClass

Expand Down Expand Up @@ -141,7 +141,9 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): List<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)

val jpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand All @@ -161,8 +163,10 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): Page<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val countQuery = QueryUtilsAdaptor.createCountQueryFor(rendered.query, null, false)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)
val countQuery = queryEnhancer.createCountQueryFor()

val sortedJpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand Down Expand Up @@ -194,7 +198,9 @@ internal object JpqlEntityManagerUtils {
pageable: Pageable,
resultClass: KClass<T>,
): Slice<T?> {
val sortedQuery = QueryUtilsAdaptor.applySorting(rendered.query, pageable.sort)
val queryEnhancer = QueryEnhancerFactoryAdaptor.forQuery(rendered.query)

val sortedQuery = queryEnhancer.applySorting(pageable.sort)

val jpaQuery = entityManager.createQuery(sortedQuery, resultClass.java).apply {
setParams(this, rendered.params)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.springframework.data.jpa.repository.query

internal object QueryEnhancerFactoryAdaptor {
fun forQuery(query: String): QueryEnhancer {
return QueryEnhancerFactory.forQuery(StringQuery(query, false))
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.SliceImpl
import org.springframework.data.jpa.repository.query.QueryUtilsAdaptor
import org.springframework.data.jpa.repository.query.QueryEnhancer
import org.springframework.data.jpa.repository.query.QueryEnhancerFactoryAdaptor
import org.springframework.data.support.PageableExecutionUtilsAdaptor
import java.util.function.LongSupplier

Expand All @@ -37,6 +38,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@MockK
private lateinit var context: RenderContext

@MockK
private lateinit var queryEnhancer: QueryEnhancer

@MockK
private lateinit var selectQuery1: SelectQuery<String>

Expand Down Expand Up @@ -69,7 +73,7 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
@Suppress("UnusedEquals")
fun setUp() {
mockkObject(JpqlRendererHolder)
mockkObject(QueryUtilsAdaptor)
mockkObject(QueryEnhancerFactoryAdaptor)
mockkObject(PageableExecutionUtilsAdaptor)

every { JpqlRendererHolder.get() } returns renderer
Expand Down Expand Up @@ -233,7 +237,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { entityManager.createQuery(any<String>(), any<Class<*>>()) } returns stringTypedQuery1
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQuery1.setFirstResult(any()) } returns stringTypedQuery1
Expand All @@ -250,7 +255,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand All @@ -273,8 +279,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryUtilsAdaptor.createCountQueryFor(any(), any(), any()) } returns countQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { queryEnhancer.createCountQueryFor() } returns countQuery1
every {
entityManager.createQuery(any<String>(), any<Class<*>>())
} returns stringTypedQuery1 andThen longTypedQuery1
Expand All @@ -300,8 +307,9 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryUtilsAdaptor.createCountQueryFor(rendered1.query, null, false)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)
queryEnhancer.createCountQueryFor()

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand Down Expand Up @@ -329,7 +337,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {

every { renderer.render(any(), any()) } returns rendered1
every { selectQuery1.returnType } returns String::class
every { QueryUtilsAdaptor.applySorting(any(), any()) } returns sortedQuery1
every { QueryEnhancerFactoryAdaptor.forQuery(any()) } returns queryEnhancer
every { queryEnhancer.applySorting(any()) } returns sortedQuery1
every { entityManager.createQuery(any<String>(), any<Class<*>>()) } returns stringTypedQuery1
every { stringTypedQuery1.setParameter(any<String>(), any()) } returns stringTypedQuery1
every { stringTypedQuery1.setFirstResult(any()) } returns stringTypedQuery1
Expand All @@ -346,7 +355,8 @@ class JpqlEntityManagerUtilsTest : WithAssertions {
renderer.render(selectQuery1, context)
selectQuery1.returnType

QueryUtilsAdaptor.applySorting(rendered1.query, pageable1.sort)
QueryEnhancerFactoryAdaptor.forQuery(rendered1.query)
queryEnhancer.applySorting(pageable1.sort)

entityManager.createQuery(sortedQuery1, String::class.java)
stringTypedQuery1.setParameter(renderedParam1.first, renderedParam1.second)
Expand Down

0 comments on commit a6d474b

Please sign in to comment.