LIKE
등의 문자열 연산을 시도하면 오류 발생c.receptionType LIKE %:keyword%
receptionType
은 Enum 타입이므로 기본 문자열 비교 연산을 사용할 수 없음@Enumerated(EnumType.STRING)
애너테이션을 사용해 Enum 값을 문자열로 DB에 저장 @Enumerated(EnumType.STRING)
private ReceptionType receptionType;
OR c.receptionType = :keyword
@Query("SELECT c FROM Competition c WHERE c.isDeleted = false AND (c.title LIKE %:keyword% OR c.receptionType = :keyword)")
Page<Competition> searchCompetition(@Param("keyword") ReceptionType keyword, Pageable pageable);
:
(콜론) 기호를 붙여야 함OR c.receptionType = keyword
OR c.receptionType = :keyword
Argument [춘천] of type [java.lang.String] did not match parameter type [com._42195km.msa.competitionservice.domain.model.ReceptionType (n/a)]
문제의 쿼리:
@Query("SELECT c FROM Competition c WHERE c.isDeleted = false AND (" +
"c.title LIKE CONCAT('%', :keyword, '%') " +
"OR c.type =:keyword " + // CompetitionType enum에 대한 비교
"OR c.receptionType =:keyword)") // ReceptionType enum과 String 비교
Page<Competition> searchCompetition(@Param("keyword") String keyword, Pageable pageable);
String 타입의 키워드 "춘천"과 Enum 타입인 type
과 receptionType
필드를 직접 비교하려고 시도하여 타입 불일치 오류 발생
@Query("SELECT c FROM Competition c WHERE c.isDeleted = false AND (" +
"c.title LIKE CONCAT('%', :keyword, '%') " +
"OR CAST(c.type AS string) = :keyword " +
"OR CAST(c.receptionType AS string) = :keyword)")
Page<Competition> searchCompetition(@Param("keyword") String keyword, Pageable pageable);
public Page<CompetitionAppResponseDto> getCompetition(String keyword, Pageable pageable) {
try {
Page<Competition> competition;
// 1. CompetitionType enum에 해당하는지 확인
boolean isCompetitionType = Arrays.stream(CompetitionType.values())
.anyMatch(type -> type.name().equals(keyword));
// 2. ReceptionType enum에 해당하는지 확인
boolean isReceptionType = Arrays.stream(ReceptionType.values())
.anyMatch(type -> type.name().equals(keyword));
if (isCompetitionType || isReceptionType) {
// enum 타입에 맞는 검색
competition = competitionRepository.searchByEnumType(keyword, pageable);
} else {
// 일반 문자열 검색 (제목만)
competition = competitionRepository.searchByTitle(keyword, pageable);
}
return competitionMapper.toAppResponseDtoPage(competition);
} catch (Exception e) {
log.error("error check : {}", e.getMessage());
throw CustomBusinessException.from(CompetitionServiceCode.COMPETITION_GET_FAIL);
}
}
// Repository 메서드 추가
@Query("SELECT c FROM Competition c WHERE c.isDeleted = false AND c.title LIKE CONCAT('%', :keyword, '%')")
Page<Competition> searchByTitle(@Param("keyword") String keyword, Pageable pageable);
@Query("SELECT c FROM Competition c WHERE c.isDeleted = false AND " +
"(CAST(c.type AS string) = :keyword OR CAST(c.receptionType AS string) = :keyword)")
Page<Competition> searchByEnumType(@Param("keyword") String keyword, Pageable pageable);
@Enumerated(EnumType.STRING)
을 사용하더라도, 문자열 파라미터와 직접 비교할 때는 타입 변환이 필요하다.CAST
함수를 사용하거나 Java 코드에서 사전에 타입 변환을 처리하는 방식이 권장된다.