MySQL - JSON 속성 순서 보장 가능하도록 (JPA)

박철현·2024년 5월 15일
0

문제해결

목록 보기
13/17
class Exam {
	@Convert(converter = 000::class)
    @Column(columnDefinition = "json")
    var exam1: LinkedHashMap<String, String> = linkedMapOf()
}

fun main() {
    		// 기존 데이터
    		val a: LinkedHashMap<String, String> = mutableMapOf(
    			"123" to "000",
    			"456" to "111111111",
    			"789" to "123"
    		) as LinkedHashMap<String, String>
    
    		// 새로운 데이터
    		val newData : LinkedHashMap<String, String> = mutableMapOf(
    			"123" to "000",
    			"789" to "123",
    			"456" to "111111111"
    		) as LinkedHashMap<String, String>
}

문제점

  • 위 예시 LinkedHashMap<String, String> 데이터에서 값은 변경 없이 순서만 변경하여 기존 엔티티의 JSON 속성에 update를 수행하고자 함
  • 하지만 update 쿼리가 발생하지 않음

시행착오 1 - 실패

  • 기존 엔티티에 저장된 Map을 clear로 명시적으로 비워주고

  • saveAndFlush() 호출 & 속성에 newData 삽입

  • update 쿼리 발생하나 DB에서 변경안됨

    • 여러 자료 및 GPT 물어보니 @OrderColumn 이라는 어노테이션 발견

      • JPA에서 순서가 있는 컬렉션 인식
      • 근데 Map은 컬렉션이 아닌데..? 하지만 일단 넣어봤지만 실패
    • 역시 사람 생각은 다들 비슷한가 선질문이 있었군..!

시행착오 2 - DB update 쿼리 날려서 문제점 확인

  • 아니 update쿼리가 발생을 하는데 왜 변하지 않을까?! 에 대한 계속 고민을 하다가 MySQL Workbench에서 직접 update 쿼리를 날려봄
  • 근데 0 change 라는것..? 엥 뭐냐너..
  • Chat GPT 갓..!

    Chat GPT 답변

    • MySQL은 일반적으로 JSON 객체의 키-값 쌍 순서를 무시하고 저장
    • 순서가 중요한 경우 배열 형태로 저장하는 것이 좋음

시행착오 3 - 순서 보장 성공적!

  • GPT 답변대로 List<Map<String, String>> 형태로 변경하여 시도
class Exam {
	@Convert(converter = 000::class)
    @Column(columnDefinition = "json")
    var exam1: List<LinkedHashMap<String, String>> = mutablelistof()
}
  • DTO 객체는 그대로 LinkedHashMap<>으로 받고, 실제 로직을 수행할 때는 List<Map<>> 형태로 시행하고 저장하도록 로직 변경
  • 문제해결!!

되는건 알겠는데 왜 되는거지?

뤼튼 답변 : JSON 객체와 배열은 다르다.

  • JSON 배열은 순서가 다르면 서로 다른 것으로 인식

  • 즉 순서만 변경 시 update 쿼리 정상 동작

  • JSON 객체: 키의 순서는 중요하지 않으며, 같은 키와 같은 값을 가지면 동일한 객체로 인식됩니다.

  • JSON 배열: 요소의 순서가 중요하며, 배열 내의 객체가 다르면 서로 다른 배열로 인식됩니다.

결론

  • MySQL에서 JSON 형태를 저장할 때 순서가 중요하다면 List<Map<>> 형태가 좋다.
    • 이렇게 해야지 단순 순서만 바뀐 결과도 업데이트가 될 수 있다!
  • 비슷한 문제를 만난다면 누군가에게 도움이 되길..!
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글