Skip to content

Commit

Permalink
hotfix: 스크롤 조회시 데이터 중복 응답 오류 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
TaeyeonRoyce committed Oct 15, 2024
1 parent ddc8bfd commit 21a1b88
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.celuveat.celeb.adapter.out.persistence.entity

import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition
import com.celuveat.restaurant.adapter.out.persistence.entity.RestaurantJpaEntity
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
Expand All @@ -9,6 +8,5 @@ interface CustomCelebrityRestaurantRepository {
fun findRestaurantsByCelebrityId(
celebrityId: Long,
pageable: Pageable,
sort: ReadCelebrityVisitedRestaurantSortCondition,
): Slice<RestaurantJpaEntity>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.celuveat.celeb.adapter.out.persistence.entity

import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition
import com.celuveat.restaurant.adapter.out.persistence.entity.RestaurantJpaEntity
import com.linecorp.kotlinjdsl.support.spring.data.jpa.repository.KotlinJdslJpqlExecutor
import org.springframework.data.domain.Pageable
Expand All @@ -15,27 +14,24 @@ class CustomCelebrityRestaurantRepositoryImpl(
override fun findRestaurantsByCelebrityId(
celebrityId: Long,
pageable: Pageable,
sort: ReadCelebrityVisitedRestaurantSortCondition,
): Slice<RestaurantJpaEntity> {
val findSlice = executor.findSlice(pageable) {
select(
entity(CelebrityRestaurantJpaEntity::class),
entity(RestaurantJpaEntity::class),
).from(
entity(CelebrityRestaurantJpaEntity::class),
fetchJoin(CelebrityRestaurantJpaEntity::restaurant),
fetchJoin(RestaurantJpaEntity::class).on(
path(CelebrityRestaurantJpaEntity::restaurant)(RestaurantJpaEntity::id).eq(
path(RestaurantJpaEntity::id)
),
),
).whereAnd(
path(CelebrityRestaurantJpaEntity::celebrity)
.path(CelebrityJpaEntity::id)
.eq(celebrityId),
).orderBy(
when (sort) {
ReadCelebrityVisitedRestaurantSortCondition.CREATED_AT -> path(RestaurantJpaEntity::createdAt).desc()
ReadCelebrityVisitedRestaurantSortCondition.REVIEW -> path(RestaurantJpaEntity::reviewCount).desc()
ReadCelebrityVisitedRestaurantSortCondition.LIKE -> path(RestaurantJpaEntity::likeCount).desc()
},
)
}
val restaurants = findSlice.content.filterNotNull().map { it.restaurant }
val restaurants = findSlice.content.filterNotNull()
return SliceImpl(
restaurants,
findSlice.pageable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import com.celuveat.common.annotation.Adapter
import com.celuveat.common.application.port.`in`.result.SliceResult
import com.celuveat.common.utils.geometry.SquarePolygon
import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition
import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition.CREATED_AT
import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition.LIKE
import com.celuveat.restaurant.adapter.`in`.rest.request.ReadCelebrityVisitedRestaurantSortCondition.REVIEW
import com.celuveat.restaurant.adapter.out.persistence.entity.InterestedRestaurantJpaRepository
import com.celuveat.restaurant.adapter.out.persistence.entity.RestaurantFilter
import com.celuveat.restaurant.adapter.out.persistence.entity.RestaurantImageJpaRepository
Expand All @@ -13,10 +16,10 @@ import com.celuveat.restaurant.adapter.out.persistence.entity.RestaurantPersiste
import com.celuveat.restaurant.application.port.out.ReadRestaurantPort
import com.celuveat.restaurant.application.port.out.SaveRestaurantPort
import com.celuveat.restaurant.domain.Restaurant
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import java.time.LocalDate
import java.time.LocalTime
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort

@Adapter
class RestaurantPersistenceAdapter(
Expand All @@ -32,11 +35,10 @@ class RestaurantPersistenceAdapter(
size: Int,
sort: ReadCelebrityVisitedRestaurantSortCondition,
): SliceResult<Restaurant> {
val pageRequest = PageRequest.of(page, size, LATEST_SORTER)
val pageRequest = PageRequest.of(page, size, getVisitedRestaurantSort(sort))
val restaurantSlice = celebrityRestaurantJpaRepository.findRestaurantsByCelebrityId(
celebrityId,
pageRequest,
sort,
)
val imagesByRestaurants = restaurantImageJpaRepository.findByRestaurantIn(restaurantSlice.content)
.groupBy { it.restaurant.id }
Expand All @@ -52,6 +54,13 @@ class RestaurantPersistenceAdapter(
)
}

private fun getVisitedRestaurantSort(sortCondition: ReadCelebrityVisitedRestaurantSortCondition) =
when (sortCondition) {
CREATED_AT -> Sort.by("createdAt").descending().and(Sort.by("id").descending())
REVIEW -> Sort.by("reviewCount").descending().and(Sort.by("id").descending())
LIKE -> Sort.by("likeCount").descending().and(Sort.by("id").descending())
}

override fun countRestaurantByCelebrity(celebrityId: Long): Int {
return celebrityRestaurantJpaRepository.countRestaurantsByCelebrityId(celebrityId).toInt()
}
Expand Down Expand Up @@ -210,7 +219,7 @@ class RestaurantPersistenceAdapter(
}

companion object {
val LATEST_SORTER = Sort.by("createdAt").descending()
val LATEST_SORTER = Sort.by("id").descending()
}

override fun save(restaurant: Restaurant) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ class CustomRestaurantRepositoryImpl(
select(
entity(RestaurantJpaEntity::class),
).from(
entity(RestaurantJpaEntity::class),
leftJoin(CelebrityRestaurantJpaEntity::class).on(
path(CelebrityRestaurantJpaEntity::restaurant)(RestaurantJpaEntity::id)
.eq(path(RestaurantJpaEntity::id)),
entity(CelebrityRestaurantJpaEntity::class),
fetchJoin(RestaurantJpaEntity::class).on(
path(CelebrityRestaurantJpaEntity::restaurant)(RestaurantJpaEntity::id).eq(
path(RestaurantJpaEntity::id)
),
),
).whereAnd(
filter.category?.let { path(RestaurantJpaEntity::category).eq(it) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,56 @@ class RestaurantPersistenceAdapterTest(
visitedRestaurants.hasNext shouldBe true
}

test("셀럽이 방문한 음식점 조회 시 페이지에 따른 중복 데이터가 존재하지 않는다.") {
// given
val savedRestaurants =
restaurantJpaRepository.saveAll(sut.giveMeBuilder<RestaurantJpaEntity>().sampleList(20))
val savedCelebrity = celebrityJpaRepository.save(sut.giveMeOne())
celebrityRestaurantJpaRepository.saveAll(
savedRestaurants.map {
CelebrityRestaurantJpaEntity(
celebrity = savedCelebrity,
restaurant = it,
)
},
)

restaurantImageJpaRepository.saveAll(
savedRestaurants.map {
sut.giveMeBuilder<RestaurantImageJpaEntity>()
.set(RestaurantImageJpaEntity::id, 0)
.set(RestaurantImageJpaEntity::restaurant, it)
.set(RestaurantImageJpaEntity::isThumbnail, true, 1)
.sampleList(3)
}.flatten(),
)

// when
listOf(
restaurantPersistenceAdapter.readVisitedRestaurantByCelebrity(
celebrityId = savedCelebrity.id,
page = 0,
size = 2,
sort = CREATED_AT,
).contents + restaurantPersistenceAdapter.readVisitedRestaurantByCelebrity(
celebrityId = savedCelebrity.id,
page = 1,
size = 2,
sort = CREATED_AT,
).contents + restaurantPersistenceAdapter.readVisitedRestaurantByCelebrity(
celebrityId = savedCelebrity.id,
page = 2,
size = 2,
sort = CREATED_AT,
).contents + restaurantPersistenceAdapter.readVisitedRestaurantByCelebrity(
celebrityId = savedCelebrity.id,
page = 3,
size = 2,
sort = CREATED_AT,
).contents
).flatten().distinctBy { it.id }.size shouldBe 8
}

test("셀럽이 많이 다녀간 순서로 음식점을 조회한다.") {
// given
val savedRestaurants = restaurantJpaRepository.saveAll(sut.giveMeBuilder<RestaurantJpaEntity>().sampleList(2))
Expand Down Expand Up @@ -133,12 +183,23 @@ class RestaurantPersistenceAdapterTest(

test("조건에 따라 음식점을 페이징 검색한다.") {
// given
restaurantJpaRepository.saveAll(
val savedRestaurants = restaurantJpaRepository.saveAll(
sut.giveMeBuilder<RestaurantJpaEntity>()
.setExp(RestaurantJpaEntity::category, "한식", 2)
.setExp(RestaurantJpaEntity::roadAddress, "서울", 1)
.sampleList(5),
)
savedRestaurants.map {
celebrityRestaurantJpaRepository.save(
sut.giveMeBuilder<CelebrityRestaurantJpaEntity>()
.set(CelebrityRestaurantJpaEntity::restaurant, it)
.set(
CelebrityRestaurantJpaEntity::celebrity,
celebrityJpaRepository.save(sut.giveMeOne<CelebrityJpaEntity>())
)
.sample()
)
}

// when
val restaurants = restaurantPersistenceAdapter.readRestaurantsByCondition(
Expand Down Expand Up @@ -178,13 +239,25 @@ class RestaurantPersistenceAdapterTest(

test("존재하지 않는 조건은 생략하고 검색한다.") {
// given
restaurantJpaRepository.saveAll(
val savedRestaurants = restaurantJpaRepository.saveAll(
sut.giveMeBuilder<RestaurantJpaEntity>()
.setExp(RestaurantJpaEntity::category, "한식", 1)
.setExp(RestaurantJpaEntity::roadAddress, "서울", 2)
.sampleList(4),
.sampleList(5),
)

savedRestaurants.map {
celebrityRestaurantJpaRepository.save(
sut.giveMeBuilder<CelebrityRestaurantJpaEntity>()
.set(CelebrityRestaurantJpaEntity::restaurant, it)
.set(
CelebrityRestaurantJpaEntity::celebrity,
celebrityJpaRepository.save(sut.giveMeOne<CelebrityJpaEntity>())
)
.sample()
)
}

// when
val restaurants = restaurantPersistenceAdapter.readRestaurantsByCondition(
category = null,
Expand Down

0 comments on commit 21a1b88

Please sign in to comment.