첫번째 에러
Caused by: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'long, long'. Cause: java.lang.ClassNotFoundException: Cannot find class: long, long
MyBatis xml 파일에서 매개변수를 두개 두고 싶어서 parameterType="long, long" 을 해봤다.
이 부분 때문에 에러가 발생해버렸다...
<insert id="addPrefer" parameterType="long, long"> // long으로 바꾸니 돌아감
insert into streamingLike(live_id, user_id)
values(#{liveId}, #{userId})
</insert>
두번째 에러
2024-05-10T13:26:07.029+09:00 WARN 16742 --- [Mytube] [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type long from Object value (token JsonToken.START_OBJECT)]
long json 을 long 타입으로 역직렬화를 하려고 했는데 실패했다는내용이다.
역직렬화가 이뤄지는 곳은 controller 이니 그 쪽 코드를 확인했다.
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/live")
public class LiveController {
@PostMapping("/{liveId}/prefer") // before
public void preferLive(@PathVariable("liveId") long liveId, @RequestBody long userId){
liveService.prefer(liveId, userId);
}
}
// After
@PostMapping("/{liveId}/prefer")
public void preferLive(@PathVariable("liveId") long liveId, @RequestBody ThumbsUpRequest request){
request.setLiveId(liveId);
// ThumbsUpRequest request = new ThumbsUpRequest(liveId, userId);
liveService.prefer(request);
}
-----
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@AllArgsConstructor
public class ThumbsUpRequest {
private long userId;
@Setter
private long liveId;
}
controller 에서 service 로 넘어갈 때 객체를 만들어 역직렬화가 되도록 바꿨다.
세번째 오류
java.lang.NullPointerException: Cannot invoke "com.flab.Mytube.service.LiveService.prefer(com.flab.Mytube.dto.movie.request.ThumbsUpRequest)" because "com.flab.Mytube.controller.LiveController.liveService" is null
선언한 서비스에 null 이 들어갔다는 걸 보고 어이가 없어서 부랴부랴 확인했다.
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/live")
public class LiveController {
private static LiveService liveService; // before
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/live")
public class LiveController {
private final LiveService liveService; // after
static -> final
네번째 오류
org.apache.ibatis.binding.BindingException: Parameter 'liveId' not found. Available parameters are [request, param1]
발생 원인
MyBatis를 이용한 SQL Mapper의 메소드는 하나의 파라미터만을 읽음.
즉, 파라미터의 개수가 2개 이상일 때 발생
- 하나의 파라미터만 읽기 때문에 2개 이상에 파라미터를 주는 경우 해당데이터가 어떤 것인지를 명시하지 않으면 에러 발생
아래 링크를 참고해서 해결했다.
[MyBatis]org.apache.ibatis.binding.BindingException: Parameter '파라미터명' not found. 에러
[MyBatis]org.apache.ibatis.binding.BindingException: Parameter '파라미터명' not found. 에러
에러 내용 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.bindi...
blog.naver.com
다섯번째 오류
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'liveId' in 'class java.lang.Long'
MyBatis 동작 과정 중 liveId 라는 변수에서 getter 를 찾고 있었다.
이에 매퍼와 관련한 코드인 걸 직감하고 확인했다.
@Component
@Mapper
public interface LiveMapper {
long getPreferCount(@Param("request") long liveId); // before
long getPreferCount(@Param("request") ThumbsUpRequest request);// after
넘겨주는 매개변수가 하나일지라도 객체로 넘겨줘야 하나보다.
지금 와서 생각해보는데 long 이란 기본 자료형인 Long 참조 자료형으로 했으면 해결 되지 않았을까?
여섯번째 오류
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.mybatis.spring.MyBatisSystemException] with root cause
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 10 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:80) ~[mybatis-3.5.7.jar:3.5.7]
sql 문이 여러게의 레코드를 결과로 던져주고 있다고 한다.
그냥 throw Exception 으로 처리하는 블로그도 보긴 했지만 내가 의도한 건 1개의 결과만 가져오는 것이었기 때문에 확인을 해봤다.
관련된 sql 문을 실행해보던 중 여러개의 레코드를 반환하는 select 를 찾아서 sql 문을 수정했다.
일곱번째 오류
with path [] threw exception [Request processing failed: org.springframework.jdbc.BadSqlGrammarException:
Error querying database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'streaming_id' in 'where clause'
The error may exist in file [/Users/aristo/Desktop/2024/f-lab/project/Mytube-streaming/Mytube/build/resources/main/mybatis/mapper/StreamingMapper.xml]
The error may involve com.flab.Mytube.mapper.LiveMapper.getPreferCount-Inline
The error occurred while setting parameters
SQL: select thumbs_up from live_streaming where streaming_id = ?
Cause: java.sql.SQLSyntaxErrorException: Unknown column 'streaming_id' in 'where clause'
; bad SQL grammar []] with root cause
java.sql.SQLSyntaxErrorException: Unknown column 'streaming_id' in 'where clause'
얼마나 실수를 했는지 모르겠다.
테이블에 없는 필드에서 데이터를 가져오려고 해서 난 에러였다.
쿼리문을 다시 작성했다.
여덟번째 오류
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap')] with root cause
java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap')
Integer 를 Long 으로 캐스트할 수 없다는 오류였다.
자바 코드에서 해당 변수를 모두 long 으로 했는데 어디서 잘못되었는지 곰곰히 생각해봤다.
그리고 문득 이 부분이 생각났다.
<select id="checkPrefer" parameterType="com.flab.Mytube.dto.movie.request.ThumbsUpRequest" resultType="long">
select count(id) from streamingLike
where streaming_id = #{request.liveId} and user_id = #{request.userId}
</select>
// resultType="long" after (before: resultType:"int")
select 문의 resultType="int" 로 되어 있었던 것이다.
DB에 int 형으로 저장했기 때문에 별다른 의심 없이 작성했었는데 long 으로 바꾸니 잘 해결되었다.
교훈
오타 조심하자.
'개발 일기' 카테고리의 다른 글
./gradlew build 의 굴레 (0) | 2024.08.02 |
---|---|
[Spring] Failed to convert value of type 'java.lang.String' to required type 'long' (0) | 2024.06.14 |