From d57df5a00aa4690fe0384e31f3e9a5f27423260d Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 16:58:38 +0900 Subject: [PATCH 1/9] =?UTF-8?q?chore:=20kotiln=20jdsl=203.0=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-app/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server-app/build.gradle.kts b/server-app/build.gradle.kts index 84cbcdd4..073b444d 100644 --- a/server-app/build.gradle.kts +++ b/server-app/build.gradle.kts @@ -16,6 +16,9 @@ dependencies { implementation(libs.spring.data.jpa) implementation(libs.hibernate.spatial) implementation(libs.kotlin.jdsl) + implementation("com.linecorp.kotlin-jdsl:jpql-dsl:3.0.0") + implementation("com.linecorp.kotlin-jdsl:jpql-render:3.0.0") + implementation("com.linecorp.kotlin-jdsl:spring-data-jpa-support:3.0.0") implementation(libs.jjwt.api) runtimeOnly(libs.jjwt.impl) From 18fca688a010669d06f6736c4c361be70b01e83f Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 16:59:19 +0900 Subject: [PATCH 2/9] =?UTF-8?q?refactor:=20=EC=8B=9D=EB=8B=B9=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=84=B0=EB=A6=AC=20jds?= =?UTF-8?q?l=203.0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RestaurantAppQueryRepositoryImpl.kt | 53 ++++++++++++------- .../service/MountainAppQueryServiceTest.kt | 3 +- .../RestaurantAppQueryRepositoryImplTest.kt | 4 +- .../service/RestaurantAppQueryServiceTest.kt | 3 +- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImpl.kt index 2fb68889..42048a88 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImpl.kt @@ -1,12 +1,9 @@ package com.santaclose.app.restaurant.repository import arrow.core.Either -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.querydsl.from.fetch -import com.linecorp.kotlinjdsl.querydsl.from.join -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery -import com.linecorp.kotlinjdsl.spring.data.singleQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.restaurant.repository.dto.RestaurantLocationDto import com.santaclose.lib.entity.location.Location import com.santaclose.lib.entity.mountain.Mountain @@ -14,32 +11,48 @@ import com.santaclose.lib.entity.mountainRestaurant.MountainRestaurant import com.santaclose.lib.entity.restaurant.Restaurant import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB -import jakarta.persistence.criteria.JoinType +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository -class RestaurantAppQueryRepositoryImpl(private val springDataQueryFactory: SpringDataQueryFactory) : +class RestaurantAppQueryRepositoryImpl( + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, +) : RestaurantAppQueryRepository { override fun findOneWithLocation(id: Long): Either = Either.catchDB { - springDataQueryFactory.singleQuery { - select(entity(Restaurant::class)) - from(Restaurant::class) - where(col(Restaurant::id).equal(id)) - fetch(Restaurant::location, JoinType.INNER) + val query = jpql { + select( + entity(Restaurant::class), + ).from( + entity(Restaurant::class), + innerFetchJoin(Restaurant::location), + ).where( + path(Restaurant::id).eq(id), + ) } + + entityManager.createQuery(query, jpqlRenderContext).singleResult } override fun findLocationByMountain(mountainId: Long): Either> = Either.catchDB { - this.springDataQueryFactory.listQuery { - selectMulti(col(Restaurant::id), col(Location::point)) - from(Mountain::class) - join(Mountain::mountainRestaurant, JoinType.INNER) - join(MountainRestaurant::restaurant, JoinType.INNER) - join(Restaurant::location, JoinType.INNER) - where(col(Mountain::id).equal(mountainId)) + val query = jpql { + selectNew( + path(Restaurant::id), + path(Location::point), + ).from( + entity(Mountain::class), + innerJoin(Mountain::mountainRestaurant), + innerJoin(MountainRestaurant::restaurant), + innerJoin(Restaurant::location), + ).where( + path(Mountain::id).eq(mountainId), + ) } + + entityManager.createQuery(query, jpqlRenderContext).resultList } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt index 0dff8ac6..31419a4d 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt @@ -1,5 +1,6 @@ package com.santaclose.app.mountain.service +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.mountain.repository.MountainAppQueryRepositoryImpl import com.santaclose.app.mountainRestaurant.repository.MountainRestaurantAppQueryRepositoryImpl import com.santaclose.app.mountainReview.repository.MountainReviewAppQueryRepositoryImpl @@ -29,7 +30,7 @@ internal class MountainAppQueryServiceTest @Autowired constructor( MountainAppQueryService( MountainAppQueryRepositoryImpl(em.createQueryFactory()), MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()), - RestaurantAppQueryRepositoryImpl(em.createQueryFactory()), + RestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()), MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()), ) diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImplTest.kt index 28472c67..14daae78 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurant/repository/RestaurantAppQueryRepositoryImplTest.kt @@ -1,10 +1,10 @@ package com.santaclose.app.restaurant.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createLocation import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainRestaurant -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import io.kotest.assertions.arrow.core.shouldBeRight import io.kotest.matchers.collections.shouldHaveSize @@ -20,7 +20,7 @@ internal class RestaurantAppQueryRepositoryImplTest @Autowired constructor( private val em: EntityManager, ) { private val restaurantAppQueryRepository = - RestaurantAppQueryRepositoryImpl(em.createQueryFactory()) + RestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindLocationByMountain { diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt index 663e011a..d3938638 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt @@ -1,5 +1,6 @@ package com.santaclose.app.restaurant.service +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.mountain.repository.MountainAppQueryRepositoryImpl import com.santaclose.app.mountainRestaurant.repository.MountainRestaurantAppQueryRepositoryImpl import com.santaclose.app.restaurant.repository.RestaurantAppQueryRepositoryImpl @@ -26,7 +27,7 @@ internal class RestaurantAppQueryServiceTest @Autowired constructor( private val em: EntityManager, ) { private val restaurantAppQueryRepository = - RestaurantAppQueryRepositoryImpl(em.createQueryFactory()) + RestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()) private val restaurantReviewAppQueryRepository = RestaurantReviewAppQueryRepositoryImpl(em.createQueryFactory()) private val mountainRestaurantAppQueryRepository = From 076a21dac7f421cd51be53cc16696647fede5ea0 Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:04:54 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor:=20=EC=82=B0=20=EB=A0=88=ED=8F=AC?= =?UTF-8?q?=EC=A7=80=ED=84=B0=EB=A6=AC=20jdsl=203.0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainAppQueryRepositoryImpl.kt | 61 ++++++++++--------- .../MountainAppQueryRepositoryImplTest.kt | 4 +- .../service/MountainAppQueryServiceTest.kt | 5 +- .../service/RestaurantAppQueryServiceTest.kt | 5 +- 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImpl.kt index 5d56bbe8..075b85a3 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImpl.kt @@ -1,13 +1,9 @@ package com.santaclose.app.mountain.repository import arrow.core.Either -import arrow.core.recover -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.querydsl.from.fetch -import com.linecorp.kotlinjdsl.querydsl.from.join -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery -import com.linecorp.kotlinjdsl.spring.data.singleQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.mountain.repository.dto.MountainLocationDto import com.santaclose.lib.entity.location.Location import com.santaclose.lib.entity.mountain.Mountain @@ -15,40 +11,47 @@ import com.santaclose.lib.entity.mountainRestaurant.MountainRestaurant import com.santaclose.lib.entity.restaurant.Restaurant import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB -import jakarta.persistence.NoResultException -import jakarta.persistence.criteria.JoinType +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository class MountainAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : MountainAppQueryRepository { override fun findOneWithLocation(id: Long): Either = - Either.catch { - springDataQueryFactory.singleQuery { - select(entity(Mountain::class)) - from(Mountain::class) - fetch(Mountain::location, JoinType.INNER) - where(col(Mountain::id).equal(id)) - } - }.recover { - if (it is NoResultException) { - null - } else { - raise(DBFailure(it)) + Either.catchDB { + val query = jpql { + select( + entity(Mountain::class), + ).from( + entity(Mountain::class), + innerFetchJoin(Mountain::location), + ).where( + path(Mountain::id).eq(id), + ) } + + entityManager.createQuery(query, jpqlRenderContext).resultList.firstOrNull() } override fun findLocationByRestaurant(restaurantId: Long): Either> = Either.catchDB { - springDataQueryFactory.listQuery { - selectMulti(col(Mountain::id), col(Location::point)) - from(Mountain::class) - join(Mountain::mountainRestaurant, JoinType.INNER) - join(MountainRestaurant::restaurant, JoinType.INNER) - join(Mountain::location, JoinType.INNER) - where(col(Restaurant::id).equal(restaurantId)) + val query = jpql { + selectNew( + path(Mountain::id), + path(Location::point), + ).from( + entity(Mountain::class), + innerJoin(Mountain::mountainRestaurant), + innerJoin(MountainRestaurant::restaurant), + innerJoin(Mountain::location), + ).where( + path(Restaurant::id).eq(restaurantId), + ) } + + entityManager.createQuery(query, jpqlRenderContext).resultList } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImplTest.kt index 0c9fb896..27419c15 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountain/repository/MountainAppQueryRepositoryImplTest.kt @@ -1,10 +1,10 @@ package com.santaclose.app.mountain.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createLocation import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainRestaurant -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import com.santaclose.lib.entity.location.Location import io.kotest.assertions.arrow.core.shouldBeRight @@ -21,7 +21,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest internal class MountainAppQueryRepositoryImplTest @Autowired constructor( private val em: EntityManager, ) { - private val mountainAppQueryRepository = MountainAppQueryRepositoryImpl(em.createQueryFactory()) + private val mountainAppQueryRepository = MountainAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindOneWithLocation { diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt index 31419a4d..da4f6b08 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt @@ -26,11 +26,12 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest internal class MountainAppQueryServiceTest @Autowired constructor( private val em: EntityManager, ) { + private val jpqlRenderContext = JpqlRenderContext() private val mountainAppQueryService = MountainAppQueryService( - MountainAppQueryRepositoryImpl(em.createQueryFactory()), + MountainAppQueryRepositoryImpl(em, jpqlRenderContext), MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()), - RestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()), + RestaurantAppQueryRepositoryImpl(em, jpqlRenderContext), MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()), ) diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt index d3938638..6d56f101 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt @@ -26,14 +26,15 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest internal class RestaurantAppQueryServiceTest @Autowired constructor( private val em: EntityManager, ) { + private val jpqlRenderContext = JpqlRenderContext() private val restaurantAppQueryRepository = - RestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()) + RestaurantAppQueryRepositoryImpl(em, jpqlRenderContext) private val restaurantReviewAppQueryRepository = RestaurantReviewAppQueryRepositoryImpl(em.createQueryFactory()) private val mountainRestaurantAppQueryRepository = MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()) private val mountainAppQueryRepository = - MountainAppQueryRepositoryImpl(em.createQueryFactory()) + MountainAppQueryRepositoryImpl(em, jpqlRenderContext) private val restaurantAppQueryService = RestaurantAppQueryService( From 3720206050be689d572e337eaa122b8511d8d328 Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:07:17 +0900 Subject: [PATCH 4/9] =?UTF-8?q?refactor:=20=EC=83=98=ED=94=8C=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=84=B0=EB=A6=AC=20jdsl=203.0=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SampleAppQueryRepositoryImpl.kt | 26 +++++++++++++------ .../SampleAppQueryRepositoryImplTest.kt | 4 +-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImpl.kt index 0f01259a..18b0ae5c 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImpl.kt @@ -1,25 +1,35 @@ package com.santaclose.app.sample.repository import arrow.core.Either -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.singleQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.sample.controller.dto.SampleAppDetail import com.santaclose.lib.entity.sample.Sample import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository class SampleAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : SampleAppQueryRepository { override fun findByPrice(price: Int): Either = Either.catchDB { - springDataQueryFactory.singleQuery { - selectMulti(col(Sample::name), col(Sample::price), col(Sample::status)) - from(Sample::class) - where(col(Sample::price).equal(price)) + val query = jpql { + selectNew( + path(Sample::name), + path(Sample::price), + path(Sample::status), + ).from( + entity(Sample::class), + ).where( + path(Sample::price).eq(price), + ) } + + entityManager.createQuery(query, jpqlRenderContext).singleResult } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImplTest.kt index 8fa4efbb..577defa5 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/sample/repository/SampleAppQueryRepositoryImplTest.kt @@ -1,7 +1,7 @@ package com.santaclose.app.sample.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.sample.controller.dto.SampleAppDetail -import com.santaclose.app.util.createQueryFactory import com.santaclose.lib.entity.sample.Sample import com.santaclose.lib.entity.sample.type.SampleStatus import io.kotest.assertions.arrow.core.shouldBeRight @@ -18,7 +18,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest internal class SampleAppQueryRepositoryImplTest @Autowired constructor( private val em: EntityManager, ) { - private val sampleAppQueryRepository = SampleAppQueryRepositoryImpl(em.createQueryFactory()) + private val sampleAppQueryRepository = SampleAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindByPrice { From deca0fcbdff321370662b3f15b137ac91533462e Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:31:39 +0900 Subject: [PATCH 5/9] =?UTF-8?q?refactor:=20=EC=82=B0=20=EC=8B=9D=EB=8B=B9?= =?UTF-8?q?=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=84=B0=EB=A6=AC=20jdsl=203.0?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppUserAppQueryRepositoryImpl.kt | 31 +++++---- ...ountainRestaurantAppQueryRepositoryImpl.kt | 64 ++++++++++++------- .../AppUserAppQueryRepositoryImplTest.kt | 4 +- .../service/MountainAppQueryServiceTest.kt | 2 +- ...ainRestaurantAppQueryRepositoryImplTest.kt | 4 +- .../service/RestaurantAppQueryServiceTest.kt | 2 +- 6 files changed, 68 insertions(+), 39 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImpl.kt index 3c5aea04..6032900b 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImpl.kt @@ -2,24 +2,33 @@ package com.santaclose.app.appUser.repository import arrow.core.Either import arrow.core.Either.Companion.catch -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.lib.entity.appUser.AppUser +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository class AppUserAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : AppUserAppQueryRepository { override fun findBySocialId(socialId: String): Either = catch { - springDataQueryFactory - .listQuery { - select(entity(AppUser::class)) - from(AppUser::class) - where(col(AppUser::socialId).equal(socialId)) - limit(1) - } + val query = jpql { + select( + entity(AppUser::class), + ).from( + entity(AppUser::class), + ).where( + path(AppUser::socialId).eq(socialId), + ) + } + + entityManager + .createQuery(query, jpqlRenderContext) + .apply { maxResults = 1 } + .resultList .firstOrNull() } } diff --git a/server-app/src/main/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImpl.kt index d282e8b0..75e72ef4 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImpl.kt @@ -1,10 +1,9 @@ package com.santaclose.app.mountainRestaurant.repository import arrow.core.Either -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.querydsl.from.join -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.mountainRestaurant.repository.dto.LatestMountainDto import com.santaclose.app.mountainRestaurant.repository.dto.LatestRestaurantDto import com.santaclose.lib.entity.mountain.Mountain @@ -12,36 +11,57 @@ import com.santaclose.lib.entity.mountainRestaurant.MountainRestaurant import com.santaclose.lib.entity.restaurant.Restaurant import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB -import jakarta.persistence.criteria.JoinType +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository class MountainRestaurantAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : MountainRestaurantAppQueryRepository { override fun findMountainByRestaurant(id: Long, limit: Int): Either> = Either.catchDB { - springDataQueryFactory.listQuery { - selectMulti(col(Mountain::id), col(Mountain::name)) - from(MountainRestaurant::class) - join(MountainRestaurant::mountain, JoinType.INNER) - join(MountainRestaurant::restaurant, JoinType.INNER) - where(col(Restaurant::id).equal(id)) - orderBy(col(Mountain::id).desc()) - limit(limit) + val query = jpql { + selectNew( + path(Mountain::id), + path(Mountain::name), + ).from( + entity(Mountain::class), + innerJoin(Mountain::mountainRestaurant), + innerJoin(MountainRestaurant::restaurant), + ).where( + path(Restaurant::id).eq(id), + ).orderBy( + path(Mountain::id).desc(), + ) } + + entityManager + .createQuery(query, jpqlRenderContext) + .apply { maxResults = limit } + .resultList } override fun findRestaurantByMountain(id: Long, limit: Int): Either> = Either.catchDB { - springDataQueryFactory.listQuery { - selectMulti(col(Restaurant::id), col(Restaurant::name)) - from(MountainRestaurant::class) - join(MountainRestaurant::mountain, JoinType.INNER) - join(MountainRestaurant::restaurant, JoinType.INNER) - where(col(Mountain::id).equal(id)) - orderBy(col(Restaurant::id).desc()) - limit(limit) + val query = jpql { + selectNew( + path(Restaurant::id), + path(Restaurant::name), + ).from( + entity(MountainRestaurant::class), + innerJoin(MountainRestaurant::mountain), + innerJoin(MountainRestaurant::restaurant), + ).where( + path(Mountain::id).eq(id), + ).orderBy( + path(Restaurant::id).desc(), + ) } + + entityManager + .createQuery(query, jpqlRenderContext) + .apply { maxResults = limit } + .resultList } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImplTest.kt index 67bbb4dc..c905bbaa 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/appUser/repository/AppUserAppQueryRepositoryImplTest.kt @@ -1,6 +1,6 @@ package com.santaclose.app.appUser.repository -import com.santaclose.app.util.createQueryFactory +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.lib.entity.appUser.AppUser import io.kotest.assertions.arrow.core.shouldBeRight import jakarta.persistence.EntityManager @@ -13,7 +13,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest internal class AppUserAppQueryRepositoryImplTest @Autowired constructor( private val em: EntityManager, ) { - private val appUserAppRepository = AppUserAppQueryRepositoryImpl(em.createQueryFactory()) + private val appUserAppRepository = AppUserAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindBySocialId { diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt index da4f6b08..2cd52c6a 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt @@ -32,7 +32,7 @@ internal class MountainAppQueryServiceTest @Autowired constructor( MountainAppQueryRepositoryImpl(em, jpqlRenderContext), MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()), RestaurantAppQueryRepositoryImpl(em, jpqlRenderContext), - MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()), + MountainRestaurantAppQueryRepositoryImpl(em, jpqlRenderContext), ) @Nested diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImplTest.kt index 7e9270ec..cdaff419 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountainRestaurant/repository/MountainRestaurantAppQueryRepositoryImplTest.kt @@ -1,9 +1,9 @@ package com.santaclose.app.mountainRestaurant.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainRestaurant -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import io.kotest.assertions.arrow.core.shouldBeRight import io.kotest.matchers.collections.shouldBeSortedWith @@ -19,7 +19,7 @@ internal class MountainRestaurantAppQueryRepositoryImplTest @Autowired construct private val em: EntityManager, ) { private val mountainRestaurantAppQueryRepository = - MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()) + MountainRestaurantAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindMountainByRestaurant { diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt index 6d56f101..6d36a2b7 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt @@ -32,7 +32,7 @@ internal class RestaurantAppQueryServiceTest @Autowired constructor( private val restaurantReviewAppQueryRepository = RestaurantReviewAppQueryRepositoryImpl(em.createQueryFactory()) private val mountainRestaurantAppQueryRepository = - MountainRestaurantAppQueryRepositoryImpl(em.createQueryFactory()) + MountainRestaurantAppQueryRepositoryImpl(em, jpqlRenderContext) private val mountainAppQueryRepository = MountainAppQueryRepositoryImpl(em, jpqlRenderContext) From d99fec5822516d9bbe9863d8f3807c817d9cd465 Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:45:01 +0900 Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20=EC=8B=9D=EB=8B=B9=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=84=B0=EB=A6=AC=20jds?= =?UTF-8?q?l=203.0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RestaurantReviewAppQueryRepositoryImpl.kt | 81 ++++++++++--------- .../service/RestaurantAppQueryServiceTest.kt | 3 +- ...taurantReviewAppQueryRepositoryImplTest.kt | 4 +- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt index 7e647eae..3ba9b5bd 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt @@ -1,14 +1,9 @@ package com.santaclose.app.restaurantReview.repository import arrow.core.Either -import arrow.core.recover -import com.linecorp.kotlinjdsl.querydsl.expression.avg -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.querydsl.expression.count -import com.linecorp.kotlinjdsl.querydsl.from.join -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery -import com.linecorp.kotlinjdsl.spring.data.singleQuery +import com.linecorp.kotlinjdsl.dsl.jpql.jpql +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.restaurantReview.repository.dto.LatestRestaurantReviewDto import com.santaclose.app.restaurantReview.repository.dto.RestaurantRatingAverageDto import com.santaclose.lib.entity.restaurant.Restaurant @@ -16,54 +11,62 @@ import com.santaclose.lib.entity.restaurantReview.RestaurantRating import com.santaclose.lib.entity.restaurantReview.RestaurantReview import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB -import jakarta.persistence.PersistenceException -import jakarta.persistence.criteria.JoinType +import jakarta.persistence.EntityManager import org.springframework.stereotype.Repository @Repository class RestaurantReviewAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : RestaurantReviewAppQueryRepository { override fun findAllByRestaurant( restaurantId: Long, limit: Int, ): Either> = Either.catchDB { - springDataQueryFactory.listQuery { - selectMulti( - col(RestaurantReview::id), - col(RestaurantReview::title), - col(RestaurantReview::content), + val query = jpql { + selectNew( + path(RestaurantReview::id), + path(RestaurantReview::title), + path(RestaurantReview::content), + ).from( + entity(RestaurantReview::class), + innerJoin(RestaurantReview::restaurant), + ).where( + path(Restaurant::id).eq(restaurantId), + ).orderBy( + path(RestaurantReview::id).desc(), ) - from(RestaurantReview::class) - join(RestaurantReview::restaurant, JoinType.INNER) - where(col(Restaurant::id).equal(restaurantId)) - orderBy(col(RestaurantReview::id).desc()) - limit(limit) } + + entityManager + .createQuery(query, jpqlRenderContext) + .apply { maxResults = limit } + .resultList } override fun findRestaurantRatingAverages(restaurantId: Long): Either = - Either.catch { - springDataQueryFactory.singleQuery { - selectMulti( - avg(RestaurantRating::taste), - avg(RestaurantRating::parkingSpace), - avg(RestaurantRating::kind), - avg(RestaurantRating::clean), - avg(RestaurantRating::mood), + Either.catchDB { + val query = jpql { + selectNew( + avg(path(RestaurantReview::rating)(RestaurantRating::taste)), + avg(path(RestaurantReview::rating)(RestaurantRating::parkingSpace)), + avg(path(RestaurantReview::rating)(RestaurantRating::kind)), + avg(path(RestaurantReview::rating)(RestaurantRating::clean)), + avg(path(RestaurantReview::rating)(RestaurantRating::mood)), count(RestaurantReview::id), + ).from( + entity(RestaurantReview::class), + innerJoin(RestaurantReview::restaurant), + ).where( + path(Restaurant::id).eq(restaurantId), ) - from(RestaurantReview::class) - join(RestaurantReview::restaurant, JoinType.INNER) - associate(RestaurantReview::class, RestaurantRating::class, on(RestaurantReview::rating)) - where(col(Restaurant::id).equal(restaurantId)) - } - }.recover { - if (it is PersistenceException) { - RestaurantRatingAverageDto.empty - } else { - raise(DBFailure(it)) } + + entityManager + .createQuery(query, jpqlRenderContext) + .resultList + .firstOrNull() + ?: RestaurantRatingAverageDto.empty } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt index 6d36a2b7..488aa998 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurant/service/RestaurantAppQueryServiceTest.kt @@ -9,7 +9,6 @@ import com.santaclose.app.restaurantReview.repository.RestaurantReviewAppQueryRe import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainRestaurant -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import com.santaclose.app.util.createRestaurantReview import io.kotest.assertions.arrow.core.shouldBeRight @@ -30,7 +29,7 @@ internal class RestaurantAppQueryServiceTest @Autowired constructor( private val restaurantAppQueryRepository = RestaurantAppQueryRepositoryImpl(em, jpqlRenderContext) private val restaurantReviewAppQueryRepository = - RestaurantReviewAppQueryRepositoryImpl(em.createQueryFactory()) + RestaurantReviewAppQueryRepositoryImpl(em, jpqlRenderContext) private val mountainRestaurantAppQueryRepository = MountainRestaurantAppQueryRepositoryImpl(em, jpqlRenderContext) private val mountainAppQueryRepository = diff --git a/server-app/src/test/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImplTest.kt index da5afddb..314690ce 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImplTest.kt @@ -1,7 +1,7 @@ package com.santaclose.app.restaurantReview.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.util.createAppUser -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import com.santaclose.app.util.createRestaurantReview import io.kotest.assertions.arrow.core.shouldBeRight @@ -19,7 +19,7 @@ internal class RestaurantReviewAppQueryRepositoryImplTest @Autowired constructor private val em: EntityManager, ) { private val restaurantReviewAppQueryRepository = - RestaurantReviewAppQueryRepositoryImpl(em.createQueryFactory()) + RestaurantReviewAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindAllByRestaurant { From ac7aa33f3fb72e9ed997b6c06e52db0797a9105d Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:54:12 +0900 Subject: [PATCH 7/9] =?UTF-8?q?refactor:=20=EC=82=B0=20=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=84=B0=EB=A6=AC=20jdsl=203.0?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainReviewAppQueryRepositoryImpl.kt | 71 +++++++++++-------- .../RestaurantReviewAppQueryRepositoryImpl.kt | 14 ++-- .../service/MountainAppQueryServiceTest.kt | 3 +- ...ountainReviewAppQueryRepositoryImplTest.kt | 4 +- .../MountainReviewAppRepositoryTest.kt | 4 +- 5 files changed, 55 insertions(+), 41 deletions(-) diff --git a/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt index 321ae892..3ec3f2a4 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt @@ -2,60 +2,69 @@ package com.santaclose.app.mountainReview.repository import arrow.core.Either import arrow.core.recover -import com.linecorp.kotlinjdsl.query.spec.expression.EntitySpec +import com.linecorp.kotlinjdsl.dsl.jpql.jpql import com.linecorp.kotlinjdsl.querydsl.expression.avg -import com.linecorp.kotlinjdsl.querydsl.expression.col -import com.linecorp.kotlinjdsl.querydsl.from.fetch -import com.linecorp.kotlinjdsl.querydsl.from.join -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactory -import com.linecorp.kotlinjdsl.spring.data.listQuery -import com.linecorp.kotlinjdsl.spring.data.singleQuery +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext +import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.mountainReview.repository.dto.MountainRatingAverageDto import com.santaclose.lib.entity.mountain.Mountain import com.santaclose.lib.entity.mountainReview.MountainRating import com.santaclose.lib.entity.mountainReview.MountainReview import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB +import jakarta.persistence.EntityManager import jakarta.persistence.PersistenceException -import jakarta.persistence.criteria.JoinType import org.springframework.stereotype.Repository @Repository class MountainReviewAppQueryRepositoryImpl( - private val springDataQueryFactory: SpringDataQueryFactory, + private val entityManager: EntityManager, + private val jpqlRenderContext: JpqlRenderContext, ) : MountainReviewAppQueryRepository { override fun findAllByMountainId(mountainId: Long, limit: Int): Either> = Either.catchDB { - springDataQueryFactory.listQuery { - val mountainReview: EntitySpec = entity(MountainReview::class) - select(mountainReview) - from(mountainReview) - fetch(MountainReview::mountain, JoinType.INNER) - where(col(Mountain::id).equal(mountainId)) - orderBy(col(Mountain::id).desc()) - limit(limit) + val query = jpql { + select( + entity(MountainReview::class), + ).from( + entity(MountainReview::class), + innerJoin(MountainReview::mountain), + ).where( + path(Mountain::id).eq(mountainId), + ).orderBy( + path(Mountain::id).desc(), + ) } + + entityManager + .createQuery(query, jpqlRenderContext) + .apply { maxResults = limit } + .resultList } override fun findMountainRatingAverages(mountainId: Long): Either = Either.catch { - springDataQueryFactory.singleQuery { - val mountainReview: EntitySpec = entity(MountainReview::class) - selectMulti( - avg(MountainRating::scenery), - avg(MountainRating::tree), - avg(MountainRating::trail), - avg(MountainRating::parking), - avg(MountainRating::toilet), - avg(MountainRating::traffic), - count(col(MountainReview::id)), + val query = jpql { + selectNew( + avg(path(MountainReview::rating)(MountainRating::scenery)), + avg(path(MountainReview::rating)(MountainRating::tree)), + avg(path(MountainReview::rating)(MountainRating::trail)), + avg(path(MountainReview::rating)(MountainRating::parking)), + avg(path(MountainReview::rating)(MountainRating::toilet)), + avg(path(MountainReview::rating)(MountainRating::traffic)), + count(MountainReview::id), + ).from( + entity(MountainReview::class), + innerJoin(MountainReview::mountain), + ).where( + path(Mountain::id).eq(mountainId), ) - associate(MountainReview::class, MountainRating::class, on(MountainReview::rating)) - from(mountainReview) - join(MountainReview::mountain, JoinType.INNER) - where(col(Mountain::id).equal(mountainId)) } + + entityManager + .createQuery(query, jpqlRenderContext) + .singleResult }.recover { if (it is PersistenceException) { MountainRatingAverageDto.empty diff --git a/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt index 3ba9b5bd..91e27304 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/restaurantReview/repository/RestaurantReviewAppQueryRepositoryImpl.kt @@ -1,6 +1,7 @@ package com.santaclose.app.restaurantReview.repository import arrow.core.Either +import arrow.core.recover import com.linecorp.kotlinjdsl.dsl.jpql.jpql import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery @@ -12,6 +13,7 @@ import com.santaclose.lib.entity.restaurantReview.RestaurantReview import com.santaclose.lib.web.exception.DomainError.DBFailure import com.santaclose.lib.web.exception.catchDB import jakarta.persistence.EntityManager +import jakarta.persistence.PersistenceException import org.springframework.stereotype.Repository @Repository @@ -46,7 +48,7 @@ class RestaurantReviewAppQueryRepositoryImpl( } override fun findRestaurantRatingAverages(restaurantId: Long): Either = - Either.catchDB { + Either.catch { val query = jpql { selectNew( avg(path(RestaurantReview::rating)(RestaurantRating::taste)), @@ -65,8 +67,12 @@ class RestaurantReviewAppQueryRepositoryImpl( entityManager .createQuery(query, jpqlRenderContext) - .resultList - .firstOrNull() - ?: RestaurantRatingAverageDto.empty + .singleResult + }.recover { + if (it is PersistenceException) { + RestaurantRatingAverageDto.empty + } else { + raise(DBFailure(it)) + } } } diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt index 2cd52c6a..82cfcf4c 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountain/service/MountainAppQueryServiceTest.kt @@ -9,7 +9,6 @@ import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainRestaurant import com.santaclose.app.util.createMountainReview -import com.santaclose.app.util.createQueryFactory import com.santaclose.app.util.createRestaurant import com.santaclose.lib.web.exception.DomainError.NotFound import io.kotest.assertions.arrow.core.shouldBeLeft @@ -30,7 +29,7 @@ internal class MountainAppQueryServiceTest @Autowired constructor( private val mountainAppQueryService = MountainAppQueryService( MountainAppQueryRepositoryImpl(em, jpqlRenderContext), - MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()), + MountainReviewAppQueryRepositoryImpl(em, jpqlRenderContext), RestaurantAppQueryRepositoryImpl(em, jpqlRenderContext), MountainRestaurantAppQueryRepositoryImpl(em, jpqlRenderContext), ) diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImplTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImplTest.kt index 2b03473e..b9897221 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImplTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImplTest.kt @@ -1,10 +1,10 @@ package com.santaclose.app.mountainReview.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.mountainReview.repository.dto.MountainRatingAverageDto import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainReview -import com.santaclose.app.util.createQueryFactory import com.santaclose.lib.entity.mountainReview.MountainRating import com.santaclose.lib.entity.mountainReview.MountainReview import com.santaclose.lib.entity.mountainReview.type.MountainDifficulty @@ -21,7 +21,7 @@ internal class MountainReviewAppQueryRepositoryImplTest @Autowired constructor( private val em: EntityManager, ) { private val mountainReviewAppQueryRepository = - MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()) + MountainReviewAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class FindMountainRatingAverages { diff --git a/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppRepositoryTest.kt b/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppRepositoryTest.kt index b8f4bbaf..5319a156 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppRepositoryTest.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppRepositoryTest.kt @@ -1,9 +1,9 @@ package com.santaclose.app.mountainReview.repository +import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.santaclose.app.util.createAppUser import com.santaclose.app.util.createMountain import com.santaclose.app.util.createMountainReview -import com.santaclose.app.util.createQueryFactory import com.santaclose.lib.entity.mountainReview.MountainRating import com.santaclose.lib.entity.mountainReview.MountainReview import com.santaclose.lib.entity.mountainReview.type.MountainDifficulty.EASY @@ -26,7 +26,7 @@ internal class MountainReviewAppRepositoryTest @Autowired constructor( private val em: EntityManager, ) { val mountainReviewAppQueryRepository = - MountainReviewAppQueryRepositoryImpl(em.createQueryFactory()) + MountainReviewAppQueryRepositoryImpl(em, JpqlRenderContext()) @Nested inner class Create { From 6abad2a38dc417158793d840001aad22674c2a6e Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 17:57:04 +0900 Subject: [PATCH 8/9] =?UTF-8?q?refactor:=20=EA=B3=BC=EA=B1=B0=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 2 -- server-app/build.gradle.kts | 1 - .../repository/MountainReviewAppQueryRepositoryImpl.kt | 1 - .../com/santaclose/app/util/EntityManagerExtension.kt | 9 --------- 4 files changed, 13 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d8335471..8c8e55d8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -38,8 +38,6 @@ jjwt-jackson = { module = "io.jsonwebtoken:jjwt-jackson", version.ref = "jjwt" } hibernate-spatial = { module = "org.hibernate:hibernate-spatial", version = "6.2.6.Final" } -kotlin-jdsl = { module = "com.linecorp.kotlin-jdsl:spring-data-kotlin-jdsl-starter-jakarta", version = "2.2.1.RELEASE" } - database-h2 = { module = "com.h2database:h2" } connector-mysql = { module = "com.mysql:mysql-connector-j" } diff --git a/server-app/build.gradle.kts b/server-app/build.gradle.kts index 073b444d..3cc78f2d 100644 --- a/server-app/build.gradle.kts +++ b/server-app/build.gradle.kts @@ -15,7 +15,6 @@ dependencies { implementation(libs.spring.security) implementation(libs.spring.data.jpa) implementation(libs.hibernate.spatial) - implementation(libs.kotlin.jdsl) implementation("com.linecorp.kotlin-jdsl:jpql-dsl:3.0.0") implementation("com.linecorp.kotlin-jdsl:jpql-render:3.0.0") implementation("com.linecorp.kotlin-jdsl:spring-data-jpa-support:3.0.0") diff --git a/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt b/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt index 3ec3f2a4..ae043a2c 100644 --- a/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt +++ b/server-app/src/main/kotlin/com/santaclose/app/mountainReview/repository/MountainReviewAppQueryRepositoryImpl.kt @@ -3,7 +3,6 @@ package com.santaclose.app.mountainReview.repository import arrow.core.Either import arrow.core.recover import com.linecorp.kotlinjdsl.dsl.jpql.jpql -import com.linecorp.kotlinjdsl.querydsl.expression.avg import com.linecorp.kotlinjdsl.render.jpql.JpqlRenderContext import com.linecorp.kotlinjdsl.support.spring.data.jpa.extension.createQuery import com.santaclose.app.mountainReview.repository.dto.MountainRatingAverageDto diff --git a/server-app/src/test/kotlin/com/santaclose/app/util/EntityManagerExtension.kt b/server-app/src/test/kotlin/com/santaclose/app/util/EntityManagerExtension.kt index 14e4133f..a813f63a 100644 --- a/server-app/src/test/kotlin/com/santaclose/app/util/EntityManagerExtension.kt +++ b/server-app/src/test/kotlin/com/santaclose/app/util/EntityManagerExtension.kt @@ -1,8 +1,5 @@ package com.santaclose.app.util -import com.linecorp.kotlinjdsl.query.creator.CriteriaQueryCreatorImpl -import com.linecorp.kotlinjdsl.query.creator.SubqueryCreatorImpl -import com.linecorp.kotlinjdsl.spring.data.SpringDataQueryFactoryImpl import com.santaclose.lib.entity.appUser.AppUser import com.santaclose.lib.entity.appUser.type.AppUserRole import com.santaclose.lib.entity.location.Location @@ -25,12 +22,6 @@ inline fun EntityManager.findAll(): List { return createQuery(query).resultList } -fun EntityManager.createQueryFactory() = - SpringDataQueryFactoryImpl( - criteriaQueryCreator = CriteriaQueryCreatorImpl(this), - subqueryCreator = SubqueryCreatorImpl(), - ) - fun EntityManager.createAppUser( user: AppUser = AppUser("name", "email", "socialId", AppUserRole.USER), ): AppUser = user.also { persist(it) } From 308787fb38e0a81107f9c59cfbca1e368c75c823 Mon Sep 17 00:00:00 2001 From: Jake Son Date: Sat, 28 Oct 2023 18:01:25 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor:=20version=20catalog=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/libs.versions.toml | 9 +++++++++ server-app/build.gradle.kts | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c8e55d8..22ea6fb7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,6 +41,10 @@ hibernate-spatial = { module = "org.hibernate:hibernate-spatial", version = "6.2 database-h2 = { module = "com.h2database:h2" } connector-mysql = { module = "com.mysql:mysql-connector-j" } +kotlin-jdsl-jpql-dsl = { module = "com.linecorp.kotlin-jdsl:jpql-dsl", version = "3.0.0" } +kotlin-jdsl-jpql-render = { module = "com.linecorp.kotlin-jdsl:jpql-render", version = "3.0.0" } +kotlin-jdsl-spring-data-jpa-support = { module = "com.linecorp.kotlin-jdsl:spring-data-jpa-support", version = "3.0.0" } + ## test spring-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" } spring-graphql-test = { module = "org.springframework.graphql:spring-graphql-test" } @@ -73,6 +77,11 @@ kotlin-libs = [ "reactor-kotlin-extensions", "jackson-module-kotlin", ] +kotlin-jdsl = [ + "kotlin-jdsl-jpql-dsl", + "kotlin-jdsl-jpql-render", + "kotlin-jdsl-spring-data-jpa-support", +] ## test kotest = ["kotest-runner-junit5", "kotest-assertions-arrow", "kotest-extensions-spring"] diff --git a/server-app/build.gradle.kts b/server-app/build.gradle.kts index 3cc78f2d..98e7189e 100644 --- a/server-app/build.gradle.kts +++ b/server-app/build.gradle.kts @@ -15,9 +15,7 @@ dependencies { implementation(libs.spring.security) implementation(libs.spring.data.jpa) implementation(libs.hibernate.spatial) - implementation("com.linecorp.kotlin-jdsl:jpql-dsl:3.0.0") - implementation("com.linecorp.kotlin-jdsl:jpql-render:3.0.0") - implementation("com.linecorp.kotlin-jdsl:spring-data-jpa-support:3.0.0") + implementation(libs.bundles.kotlin.jdsl) implementation(libs.jjwt.api) runtimeOnly(libs.jjwt.impl)