본문 바로가기

개발/SpringBoot

[StudyHub] unknown column '필드명' in 'field list' 에러 해결

 

서론


 

unkown column ~~ in field list 에러가 발생하기 하루 전, 엔티티의 테이블명, 컬럼 이름을 바꾸고 로컬에서 테스트를 마친 뒤 배포 서버에 배포했지만..

 

 

게시글 전체 조회, 회원사진 저장, 회원 삭제 API가 정상적으로 동작하지 않는다는 프론트분의 메시지를 받았다.

 

로컬 테스트 환경에서는 잘 동작하는 것만 믿고 배포 환경에서 제대로 테스트해보지 못한게 불찰이었다.

 

흔들리는 멘탈을 부여잡고 팀원분과 함께 원인 분석을 해보았다.

 

 

 

문제 발생


 

스터디허브는 블루그린 배포 방식을 이용해 배포하기 때문에 main 브랜치에 커밋 할때마다 기존 서버가 종료되고 새로운 서버가 실행된다.

 

이 때 만약 ddl auto를 create로 잡게되면 매번 DB 테이블에 있는 튜플들이 초기화된다.

 

곧 서비스 출시를 앞두고 있기 때문에 이러한 상황을 막고자 ddl auto 값을 none으로 잡고 스키마 정보가 수정될 경우 직접 RDB를 수정해주는 방식으로 데이터베이스를 관리했다.

 

 

또한 로컬 환경도 실 배포환경과 동일하게 맞추기 위해 ddl auto 값을 none으로 설정하고 schema.sql 파일을 이용해 테이블을 생성해줬다.

 

하지만 배포 환경에서 API를 호출하니 500에러가 발생했다.

 

로그를 확인하니 unknown column 'user_id' in 'field list' 에러를 뱉어냈다.

 

단위 테스트도 돌려보고 로컬 환경에서 스웨거를 통해 테스트도 해봤지만 해결하지 못해 결국 schema.sql과 RDB의 컬럼들을 하나씩 비교하기로 결정했다.

 

 

 

 

문제 해결


 

schema.sql과 RDB의 컬럼들을 비교하던 중 Study 테이블에서 다른 점을 발견했다.

 

CREATE TABLE study
(
    study_id           BIGINT NOT NULL AUTO_INCREMENT,
    title              VARCHAR(55)   DEFAULT NULL,
    content            VARCHAR(255)  DEFAULT NULL,
    study_start_date   DATE          DEFAULT NULL,
    study_end_date     DATE          DEFAULT NULL,
    chat_url           VARCHAR(100)  DEFAULT NULL,
    user_id            BIGINT NOT NULL,
    PRIMARY KEY (study_id)
);

 

schema.sql에서는 user_id가 존재했고 RDB에서는 다른 컬럼명인 master_user_id라는 컬럼이 존재했던 것이 문제였다.

 

이것 때문에 Study 엔티티 관련 API를 호출할 때 user_id 라는 컬럼을 찾지 못해 에러가 발생한 것이었다.

 

로컬에서 잘 동작하던것으로 보아 역시 코드에서도 아래와 같이 user_id라고 설정을 해뒀었다.

 

 

 

해당 엔티티를 매개변수로 StudyEntity에 대해 CrudRepository 인터페이스의 save 메서드를 호출할 경우 아래와 같이 user_id라는 컬럼명을 이용해서 데이터를 삽입하려고 하는데 RDB에는 user_id 라는 컬럼이 존재하지 않기 때문에 에러가 발생할 수 밖에 없는 것이다.

 

 

 

해당 필드를 RDB 컬럼명과 맞춰준 뒤 배포하고 다시 실행해보았다.

 

 

 

 

 

 

잘 실행되는 모습이다.

 

 

 

 

결론


 

확실히 실 서비스 운영을 할 준비를 하니 기존에 토이 프로젝트를 개발하던 방식과 차이가 느껴진다.

 

만약 서비스 운영중에 DB 내부 스키마를 변경하다가 이런 오류가 발생했다면.. 게시글 조회 장애로 이어졌을 것이고 사용자들은 아무것도 못하는 무서운 상황에 처했을것이다.

 

그렇기에 이런 문제를 예방하기 위해 초기 ERD를 설계할 때 확실하게 설계하고 가야겠다고 생각했다.

 

서비스 출시 이후 최대한 변경사항이 적게 ERD 설계를 거듭해 나가야겠다.   

 

 

여담으로 게시글 조회 API는 빈 문자열을 보냈을 때 전체 게시글을 반환해야 하는데 빈 문자열을 보냈을 때 BooleanExpression의 반환값을 null로 반환해서 생긴 문제였다 ㅠㅠ