최근 진행하는 프로젝트에서 enum 클래스만을 저장하는 테이블이 필요해졌고, 컬럼은 오직 enum 클래스 하나만 달랑 존재했습니다. 그렇기에 해당 필드만을 PK로 갖는 테이블을 생성하고 save를 통해서 저장하는 api를 제작하는 중 insert쿼리가 아니라 update 쿼리를 수행하는 현상을 마주하였습니다.
@Table
data class Favorite(
@Id
@Column
val category : IngredientCategory,
) {
fun toResponse() : FavoriteResponseDto = FavoriteResponseDto(category = category)
}
테이블은 위와 같고, Service 계층의 코드는 아래와 같습니다.
/**
* 즐겨찾기 재료 추가하기
*/
@Transactional
suspend fun createNewFavorite(favoriteRequestDto: FavoriteRequestDto) : FavoriteResponseDto {
val category = favoriteRepository.findByCategory(favoriteRequestDto.category)
if (category != null) {
throw RuntimeException("이미 추가된 재료입니다!")
}
val result = favoriteRepository.save(favoriteRequestDto.toEntity())
return result.toResponse()
}
이 코드에서는 update 쿼리만을 수행합니다.
Repository가 제공하는 save 메소드는 id 필드가 존재하면 새로운 레코드가 아니라 기존의 레코드를 수정하는 방식으로 동작하게 됩니다. 즉, 제가 작성한 테이블은 PK 하나밖에 없는 테이블이므로 모든 동작이 update로 인식되는 것입니다.
이를 해결하기 위해서 엔티티를 아래와 같이 수정해주었습니다.
@Table
data class Favorite(
@Id
@Column
val category : IngredientCategory,
) : Persistable<IngredientCategory> {
override fun isNew(): Boolean {
return true
}
override fun getId(): IngredientCategory = this.category
fun toResponse() : FavoriteResponseDto = FavoriteResponseDto(category = category)
}
Persistable을 상속받아 isNew를 재정의하여 새로운 객체인지 아닌지 판단하도록 임의로 설정할 수 있습니다.
이제 잘 수행되네요 :)