ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [트러블슈팅] SQL Error: 1364 - Field '컬럼명' doesn't have a default value
    ERROR 2025. 4. 1. 01:40

     

    이미 로컬에서 개발을 마치고 프론트엔드 연동을 위해 서버를 띄워놓은 채로 그냥 기다리고 있었는데

    프론트엔드 측에서 스웨거 동작시 Field 'member_club_id' doesn't have a default value [insert into likes (article_id, member_id)] 라는 에러가 뜬다는 메세지를 받았다.

     

    스웨거 내 오류 메세지

    SQL Error: 1364, SQLState: HY000
    ~.SqlExceptionHelper   : Field 'member_club_id' doesn't have a default value
    ~.GlobalExceptionHandler     : [WARNING] Internal Server Error : could not execute statement [Field 'member_club_id' doesn't have a default value] [insert into likes (article_id,member_id) values (?,?)]

     

     

    분명히 로컬 및 로컬 스웨거로 동작 및 테스트를 다 해봤는데 배포 서버에서만 이런 에러가 발생하는 것이다...

     

     

    결론부터 말하자면,

    SHOW CREATE TABLE [테이블명]; SQL문을 실행해서 실제 DB의 스키마 구조와 Entity에서 정의한 구조와 같은지 한번 확인해보자!!!

     

     

     

     

    문제 현상

    특정 API 요청 (좋아요 토글) 시 다음과 같은 MySQL 오류 발생:

    Field 'member_club_id' doesn't have a default value
    [insert into likes (article_id, member_id)]


    로컬(MariaDB)에서는 동작,
    운영환경(MySQL)에서는 실패했다.

     

     

    그래서 알아본 결과 MariaDB와 MySQL은 같은 쿼리/DDL에 대해 다르게 동작할 수 있고, 특히 NOT NULL + DEFAULT 없음 상황에서 MariaDB가 더 느슨하게 처리하는 경향이 있다고 한다.

    먼저 cascade = CascadeType.ALL 제거해보고, 안돼서 orphanRemoval = true도 제거해보았다.

    그런데 둘 다 시도해본 결과 그 문제는 아니었다.

     

    다음으로 영속성을 확인해주었다. 좋아요 Likes 테이블을 저장할 때 Member도 함께 연관되어 있고, member과 member_club은 1:n으로 연결되어 있기 때문에  JPA는 Member.memberClubs 도 같이 flush(영속화)하려고 해서 이러한 문제가 발생하는 건 아닐 까 생각이 들어서 아래 4가지를 시도해보았다.

    1. member.getMemberClubs().clear()
    2. Member.builder().id(...) 프록시 사용
    3. @Transactional(readOnly = true) 사용
    4. entityManager.detach(member)
    Likes를 저장할 때 Member도 함께 연관되어 있기 때문에

    JPA는 Member.memberClubs 도 같이 flush(영속화)하려고 하고,
    그 안에서 member_club_id 필드가 NOT NULL인데 값이 없기 때문에 DB 레벨에서 에러가 발생하는 줄 알고 여러가지를 시도해보았으나 전부 되지 않아서 골머리를 앓고 있었다...,,




    따라서 의심 대상을 전환 DB 테이블 구조 자체로 이동해보았다. 그래서 
    SHOW CREATE TABLE likes;를 해보니 로컬 DB와 구조가 달랐다....

    배포를 초기에 미리해놓고 ddl-auto를 update로 설정해놓아서 entity가 변경되어도 반영되지 않았던 것이다.
    따라서 과거에 사용하던 member_club_id 컬럼이 DB에 남아 있어서 데이터 삽입시 저장에 실패했던 것이다.


    ALTER TABLE likes DROP FOREIGN KEY [키];
    ALTER TABLE likes DROP COLUMN member_club_id;
    이후 Likes insert 시 더 이상 member_club_id가 요구되지 않았고 오류를 완전히 해결할 수 있었다.

     




    교훈)
    엔티티 구조를 변경하고 반영 항상 로컬과 운영 서버의 DB에 접근하여 SHOW CREATE TABLE로 실제 반영 여부를 확인해보자..!!!

Designed by Tistory.