[TIL]토이프로젝트 오류 해결 과정

서연·2023년 9월 8일

toy-project-1

목록 보기
5/5
post-thumbnail

1. 현재 하고 싶은 것

  1. chatGPT api를 통해 내가 작성한 일기 내용과 일기에서 추출한 오늘의 감정을 바탕으로 GPT와 상담대화를 한다.
  2. 상담이 종료되면 상담 내용을 'Message' 엔티티에 저장한다.
  3. Message 내용에 대한 request example
{
    "diaryName": "user3@email.com 2023-09-06",
    "conversation": [{"role":"user", "content": "오늘은 정말 힘든 하루였어..."}, {"role":"assistant", "content": "그랬구나 어떤 일이 있었어? 이야기 해보자."},  {"role":"user", "content": "오늘 일을 늦게 해서 과장님께 혼났어."}, {"role":"assistant", "content": "정말 힘든 하루였겠다."}, {"role":"user", "content": "그래도 얘기하니까 좀 낫다."}, {"role":"assistant", "content": "도움이 되었다니 기쁩니다."}]
} 
  1. 즉, conversation 내용은 리스트 안에 딕셔너리들이 들어있는 구조이다. List<Map<String, String>>
  2. 따라서 해당 Json 구조를 읽고 string화 해서 DB에 저장하는 Converter에 대한 구현이 필요하다.

이 과정에서 마주했던 여러 에러들과 해결 방안에 대해 공부해보겠다.
현재 4, 5번 과정을 해결하지 못해서 자꾸 에러를 마주하고 있다.

1. SQL Error

상황

SQL Error: 1366, SQLState: HY000
Incorrect string value: '\xAC\xED\x00\x05ur...' for column 'conversation' at row 1
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only] with root cause

JPA에 conversation 내용을 저장하는 과정에서 위의 에러가 발생했다.

검색 결과 유추 가능한 원인

  • MySQL의 언어 설정이 UTF-8로 되어 있지 않아서 발생하는 문제

궁금증

  • spring.datasource.url 여기서 설정하는 serverTimezone=UTC&characterEncoding=UTF-8 이것은 MySQL 언어설정이 UTF-8이라는 걸 의미하지는 않는 것인가?
  • 또한 ddl-auto 속성을 최초에 create, create-drop으로 사용하면 DEFAULT CHARSET=uft8 옵션이 적용되지 않는다고 한다. (근데 나는 지금 update를 꾸준히 사용 중이긴 하다.)
    ➡️ conversation 테이블에 대해서 columnDefinition = "TEXT" 설정을 해두었는데 이 과정이 문제를 일으킨 것으로 추측된다.
    @Convert(converter = ConversationConverter.class) // @Convert 어노테이션을 사용하여 컨버터를 지정
    @Column(name = "conversation", columnDefinition = "TEXT")
    private List<Map<String,String>> conversation;
  • columnDefinition = "TEXT"로 설정하면
    • TEXT는 텍스트 데이터를 저장하기 위한 데이터 유형을 지정하는 것이며, 주로 문자열 형태의 긴 텍스트를 저장할 때 사용
    • 긴 텍스트를 저장할 수 있게 되어서, 문자열 데이터의 길이에 제한이 없거나 큰 길이를 지원한다.
    • 하지만 'TEXT' 데이터 유형 자체는 문자인코딩을 명시적으로 지정하지 않으므로, 데이터베이스 설정에서 기본 문자 인코딩이나 테이블 또는 컬럼 레벨에서 명시적으로 설정해야 한다.

해결 방법 (해결 안 됨)

  • 검색결과가 제시한 해결방법은 테이블이 만들어진 후 DB에서 직접 테이블 속성을 변경하는 것이다.
mysql > ALTER TABLE [테이블 명] convert to charset uft8;
  • 또한 데이터 베이스 생성 시 언어 설정을 다음과 같이 하기를 권장한다.
mysql > CREATE DATABASE [데이터베이스 명] CHARACTER SET utf8 COLLATE uft8_general_ci;

=> 그러나 해결되지 않았다.
utf8은 ambiguous한 표현이므로 utf8mb4를 권장했다.
구글링해보니 이모지까지 표현하고 싶은 경우 utfmb4를 사용하는 추세인 것 같다.
utfmb3도 deprecated된 상태라고...

  • utfmb4에 대한 설정은 또 다르게 해야하는 것 같다.
    application.properties에서는 다음으로 바꾸었다.
spring.datasource.url=jdbc:mysql://localhost:3306/toy?serverTimezone=UTC&character_set_server=utf8mb4

여전히 같은 에러 발생

  • message table은 utf8mb3로 생성되어 있음

해결 방법2

  • 결국 MySQL 설정 문제가 아니었다.
  • Convert 과정에서 Java 객체를 현재 잘 매핑하지 못하고 있는 듯하다.

➡️ 데이터 구조 상 리스트 안에 딕셔너리가 여러 개 있는 구조로 저장이 힘든 것 같아서 결국 딕셔너리(JSON) 한 줄씩 MySQL 저장하는 방식으로 해결

profile
삽질 기록장/ 📍다른 삽질 기록장 https://sqlimblife.tistory.com/

0개의 댓글