2024. 10. 20. 15:00ㆍ오류 극복기
사이드 프로젝트를 진행하던 중에,,,
문제가 하나 발생했다!
BaseTimeEntity로 만들어주고 필요한 테이블마다 상속을 받아서 쓰고 있었다.
@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class BaseTimeEntity {
@Column(columnDefinition = "TIMESTAMP(6)", name = "created_at", nullable = false, updatable = false)
@CreatedDate
var createdAt: LocalDateTime = LocalDateTime.now()
protected set
@Column(columnDefinition = "TIMESTAMP(6)", name = "updated_at", nullable = false)
@LastModifiedDate
var updatedAt: LocalDateTime = LocalDateTime.now()
protected set
@Column(columnDefinition = "TIMESTAMP(6)", name = "deleted_at", nullable = true)
var deletedAt: LocalDateTime? = null
}
줄곧 이렇게 써왔는데,,, 문제는 @LastModifiedDate 때문에,,, 좋아요를 눌러도 디비가 반영이 된다는 점이다...
좋아요를 누를때는 updatedAt의 변화를 주기 싫었다...
그래서 dto를 가져오는 것으로 수정을 가해봤지만,,,
유저 로그인을 한 기준으로 반영이어서,, 결국 내가 좋아요 누른 수만 나오는게 아니겠는가?
나는 총 그 댓글의 좋아요 수를 하고자 한건데,,,
그럼 좋아요 상태라고 그거와 별 다르지 않나 생각이 들었다...
그래서 고민을 좀 했다...
1. 좋아요 카운트 하는 것때문에 디비가 변경되어서 updatedAt이 좋아요를 누를때마다 변경이 된다는 점.
2. 그래서 내용이 수정됐을 경우 updatedAt을 사용 못하는 점 ? 그럼 과연 updatedAt의 필요성에 대해서 의문성을 갖게 되었다...
3. 또한 그렇다고 수정된 내용만 있을 경우를 식별하기 위해서 다른 컬럼을 추가하자니 투머치한 느낌? 불필요하다는 점
일부만 반영되도록 할 수 있는 방법은 없을까?
하면서 엄청 검색을 해보고 시도해봤던 것 같다..
해당 좋아요 테이블에 카운트를 추가하는 건?
-- > 으음,, 그건 아무래도 이상할 것 같다.. 왜냐하면 좋아요가 한두개가 아닐텐데 그때마다 하나하나 카운트 당하는 것은 옳지 않으니까? 뭔가 자그만한 일을 해결하기 위해 큰 것을 건드린 느낌이랄까?
음 그럼 likeCount 컬럼을 제거하고 size로 하는건?
위에서 말한 것처럼 엄청나게 시도를 해봤는데... 내가 좋아요 누른 수만 나왔다... 이것도 사실 정확한 원인을 몰라서... 추후에 다시 살펴보려고 한다..
그래서 좀 찾아보니,
@PreUpdate 사용하여 @LastModifiedDate 대체하기 하는 방법도 있다고 한다..
이는 이전 상태를 저장했다가 엔티티가 업데이트 되면 값을 비교하여 특정 필드가 수정될 때에만 date를 갱신할 수 있는 것이다. 하지만 이전 상태를 계속 가지고 있어야 하고 관련된 필드가 늘어날 때마다 isModified()라는 메소드를 설정해줘야 하는 번거로움이 존재한다고 한다..
그래서 내가 선택한 방법은? 바로 JPQL를 사용하는 방법이었다.
@LastModifiedDate 는 JPA의 내부 이벤트 처리 메커니즘에 의해 관리되고 엔티티가 JPA에 의해 관리되는 경우에만 자동으로 업데이트되기때문에 직접 JPQL(Java Persistence Query Language)을 사용하여 업데이트 쿼리를 실행할 때는 작동하지 않는다고 한다... 그래서 이를 이용하여 내가 필요한 요구를 들어맞게 수정할 수 있었다...
@Modifying
@Query("UPDATE Comment SET likeCount = :likeCount WHERE id = :id")
fun updateLikeCount(@Param("id") id: Long, @Param("likeCount") likeCount: Int)
이렇게 수정해주었고,,,
사실 이 좋아요가 유저 로그랑 관련된 부분이 있어서
좋아요를 누를때는 상관없는데 취소할 경우
유저 기록에 있는 컬럼도 삭제해야하기 때문에
@Modifying
@Query("DELETE FROM UserLog ul WHERE ul.commentLikeId.id = :commentLikeId")
fun deleteUserLogCommentLikeId(@Param("commentLikeId") commentLikeId: Long)
이 값도 추가해주었다...
그리고 서비스 로직에 추가하니 다행히 내가 생각했던 대로 updatedAt는 변경이 되지 않으면서 좋아요를 생성하고 취소할 수 있었다...
이후에 리팩토링할때 최대한 쿼리가 덜 발생하는 것도 고려해봐야겟다...
'오류 극복기' 카테고리의 다른 글
TIL 20241021 - 코딩테스트 정리 (1) | 2024.10.21 |
---|---|
TIL 20240104(오류 발생) Could not write JSON: Infinite recursion (0) | 2024.01.04 |
쉬어가는 오류 극복기 (0) | 2023.12.20 |
오류 발생! 그러나 극복(!) 6 (0) | 2023.12.09 |
Uncaught TypeError: Cannot read property 'addEventListener' of null 에러 (0) | 2023.11.14 |