베어_
TechBear
베어_
전체 방문자
오늘
어제
  • 분류 전체보기 (336)
    • Spring (33)
      • 개념 (13)
      • Security (5)
      • 실습 (1)
      • 토비 스프링 (11)
    • JPA (6)
    • 프로젝트 기록 (24)
    • DB (13)
    • JAVA (18)
    • 알고리즘 (50)
      • 유형정리 (8)
      • Baekjoon (21)
      • LeetCode (18)
    • 디자인패턴 (0)
    • 개발서적 (79)
      • Effective Java (78)
      • 객체지향의 사실과 오해 (1)
    • 독후감 (4)
    • 보안 (2)
    • 운영체제(OS) (53)
      • 공룡책 (53)
    • 컴퓨터 네트워크 (28)
      • 컴퓨터 네트워크 하향식 접근 (23)
    • 자료구조 (1)
    • DevOps (2)
    • 앱 개발 (20)
      • 안드로이드 스튜디오 (20)

블로그 메뉴

    공지사항

    인기 글

    태그

    • 백준
    • 자바
    • 스프링시큐리티
    • 함수형인터페이스
    • 자바8
    • 토비스프링
    • BFS
    • dfs
    • 데이터베이스
    • C++
    • 스레드
    • 스프링
    • java
    • 이펙티브자바
    • 알고리즘
    • leetcode
    • 운영체제
    • jpa
    • 코드업
    • Spring

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    베어_

    TechBear

    [Debug] MyBatis IndexOutBoundsException
    프로젝트 기록

    [Debug] MyBatis IndexOutBoundsException

    2022. 6. 8. 15:32

    에러 코드

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. 
    Cause: java.lang.IndexOutOfBoundsException: Index 4 out of bounds for length 4 
    ### The error may exist in com/example/demo2/mapper/SiteUserMapper.java (best guess) 
    ### The error may involve com.example.demo2.mapper.SiteUserMapper.getAllUser 
    ### The error occurred while handling results ### SQL: select * from SiteUser 
    ### Cause: java.lang.IndexOutOfBoundsException: Index 4 out of bounds for length 4

     

    Mapper 인터페이스를 이용하여 모든 유저의 정보를 가져오는 코드를 작성했는데 위와 같은 에러 코드가 발생하였다. 아무리 생각해도 IndexOutOfBoundsException이 나올 수 없는 구조인데 이상하여 domain 객체를 확인해보았다.

     

    문제의 원인

       문제의 원인은 @Builder와 @Data 어노테이션에 있었다.

    @Data
    @Builder
    public class SiteUser implements UserDetails {
    
        private Long id;
        private String email;
        private String password;
        private String username;
        private Collection<GrantedAuthority> authorities;
    }

     

    [@Data]

       @Data 어노테이션은 @Getter @Setter @ToString @EqualsAndHashCode @RequiredArgsConstructor 역할을 한다. SiteUser에는 final이 붙은 필드가 없기 때문에 다음과 같은 default 생성자만 가지고 있다.

    public SiteUser() {}

     

    [@Builder]

       이 메서드를 이용하면 다음과 같은 모든 필드를 가진 생성자가 생성되며, 컴파일러는 더 이상 default 생성자를 제공하지 않는다. 

    public SiteUser(Long id, String email, String password, String username, Collection<GrantedAuthority> authorities) {
        this.id = id;
        this.email = email;
        this.password = password;
        this.username = username;
        this.authorities = authorities;
    }

     

    Mybatis는 결과를 매핑할 때, 파라미터 없는 생성자로부터 객체를 얻고 setter 메서드를 호출하기 때문에 default 생성자가 없는 부분에서 문제가 생긴다. 

     

    문제 해결

        default 생성자를 만들어 주면 된다. 다음과 같이 @NoArgsConstructor를 추가해준다.

    NoArgsConstructor

    NoArgsConstructor를 추가해주면 Builder에 오류 표시가 뜬다. 

    Lombok 공식 문서 중(中)

    applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself. 

    만약에 어떤 형태의 생성자던지 클래스 파일에 존재하면 AllArgsConstructor가 생성되지 않는다. 여기서는 NoArgsConstructor를 통해 default 생성자가 생성이 되었고 따라서 Builder에 필요한 모든 인자를 가진 생성자가 생성되지 않아 에러가 생긴다. 

     

    따라서 @AllArgsConstructor도 추가해주어야 한다.

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class SiteUser implements UserDetails {
        private Long id;
        private String email;
        private String password;
        private String username;
        private Collection<GrantedAuthority> authorities;
    }

     

    정리

       에러의 원인 : Lombok 어노테이션의 미숙한 사용

       에러의 해결 : @NoArgsConstructor와 @AllArgsConstructor 추가

      '프로젝트 기록' 카테고리의 다른 글
      • [리팩토링] Pageable을 이용한 페이징
      • [회고록] 서비스 오픈 회고
      • [TDD] TDD 회고
      • [리팩토링] 일급 컬렉션
      베어_
      베어_
      Today I learned | 문제를 해결하는 개발자

      티스토리툴바