조회수 증가 구현을 위해 Repository에 다음 코드를 작성했다.
@Modifying
@Query("UPDATE WikiPage w SET w.views = w.views + 1 WHERE w.id = :wikiId")
fun updateViews(wikiId: Long)
그리고 실행했을 때 다음과 같은 예외가 발생했다.
다른 프로젝트에서는 위 쿼리 메서드가 문제없이 실행되었지만 현재 프로젝트에서는 원하는 대로 작동하지 않았다.
query executed via 'getresultlist()' or 'getsingleresult()' must be a 'select' query
[update wikipage w set w.views = w.views + 1 where w.id = :wikiid]
그래서 QueryDSL을 사용해 다음과 같이 구현했다.
fun updateViews(wikiId: Long) {
queryFactory.update(wikiPage)
.set(wikiPage.views, wikiPage.views.add(1))
.where(wikiPage.id.eq(wikiId))
.execute()
}
실행했을 때 정상적으로 조회수가 증가되는 것을 확인했는데 테스트 코드에서는 조회수 반영이 정상적으로 되지 않았다.
실패한 테스트 코드는 다음과 같다.
@Test
fun `게시물 단건 조회를 하는 경우 조회수 증가`() {
val wikiId = 1L
wikiPageRepository.updateViews(wikiId)
wikiPageRepository.flush()
val result = wikiPageRepository.findByIdOrNull(wikiId)
result?.views shouldBe 1
}
해당 코드가 실패하는 이유는 테스트 코드 수행 전 setup 메서드를 통해 저장되는 데이터들이 영속성 컨텍스트에 저장되는데 위 코드에서 wikiPageRepository.updateViews(wikiId)는 DB에 직접 쿼리를 날린다.
그리고 다시 wikiPageRepository.findByIdOrNull(wikiId)로 데이터를 가져올 때는 DB에서 가져오는 것이 아닌 영속성 컨텍스트에 있는 데이터를 가져오기 때문에 원하는 결과가 나오지 않는 것이다.
@BeforeEach
fun setup() {
wikiPageRepository.saveAllAndFlush(DEFAULT_WIKIPAGE_LIST)
}
companion object {
private val DEFAULT_WIKIPAGE_LIST = listOf(
WikiPage.from(
request = CreateWikiPageRequest(
title = "title 1",
content = "content 1",
tag = "tag 1"
)
)
}
이 문제점을 해결하기 위해 엔티티의 데이터를 변경하는 방식으로 코드를 변경했다.
@Entity
@Table(name = "wiki_page")
class WikiPage private constructor(
// ...
) : BaseTimeEntity() {
// ...
var views: Long = 0
protected set
// ...
fun updateViews() {
this.views += 1
}
// ...
}
그리고 테스트 코드 또한 다음과 같이 변경했다.
@Test
fun `게시물 단건 조회를 하는 경우 조회수 증가`() {
val wikiId = 1L
val wikiPage = wikiPageRepository.findByIdOrNull(wikiId)
wikiPage?.updateViews()
wikiPageRepository.saveAndFlush(wikiPage!!)
val result = wikiPageRepository.findByIdOrNull(wikiId)
result?.views shouldBe 1
}
위와 같이 변경 후 테스트도 정상적으로 수행되고 코드 수도 많이 줄어들었다.
'TIL(Today I Learned)' 카테고리의 다른 글
TIL - Apache Tika로 이미지 타입 검사 (0) | 2024.07.09 |
---|---|
TIL - Apache JMeter를 이용한 성능 테스트 (0) | 2024.07.08 |
TIL - Spring Boot에서 In-memory Cache 적용 (0) | 2024.07.04 |
TIL - Spring Boot Test 시 JPA metamodel must not be empty (0) | 2024.07.03 |
TIL - AWS Elastic Beanstalk 배포 후 413 Request Entity Too Large (0) | 2024.07.01 |