진짜 오랜만에 벨로그에 글을 작성하게 되었는데
최근 Java, JPA, DB관련해서 수업을 진행 중이나 글로 정리를 안 하다 보니까
자주 잊어버리기도 하고 실습 예제 하면서 배우는게 더 많아져서
트러블 슈팅/ 문제 해결 관련해서 찾은 자료는 어느정도 남겨두기로 했다.
JPA수업중 Hibernate를 사용하여 DB와 연동시키고 Entity와 영속시키는등의 수업을 진행하였는데
도중에 Db의 PK를 배정해주기위해서 GenerationType을 사용하였다.
이때 mysql을 사용하였고 GenerationType을 Auto(기본값)을 주고 사용하였는데.
H2 db를 사용할때는 정상적으로 기본키값이 배정되었으나
이상하게 mysql에서는 키값이 2부터 배정되는 상황이 나왔고,
그로인해 오류를 해결하고자 여러가지 시도를 해보다가 결국 방법을 찾아서 기록해둔다.
먼저 JPA가 제공하는 DB 기본 키 할당 전략은 직접 할당 방식과 자동 할당 방식 두 가지인데
첫번째는 말그대로 @id를 사용하여 직접 키를 할당해주는 방식이고
두번째가 애를먹었던 부분으로 GenerationType을 사용하여 자동적인 키할당을 해준다.
이때 자동 키할당 방식에는 4가지 정도가 있는데
이정도로 간결하게 볼수 있고, 결론부터 말하자면 문제가 생겼던
Auto부분의 경우에는 Hibernate가 버전업 되면서
기존의 LegacyFallbackInterpreter 방식에서 FallbackInterpreter 방식으로 변경됐다.
DB 에서 SEQUENCE 를 제공한다면 SEQUENCE 생성기가 사용되고,
지원하지 않는다면 TABLE 생성기가 대신 사용 된다.
그로인해 mysql에서는 Sequence 지원하지 않음으로 table로 동작하였고
외래키 설정으로 인해 major_id에서 미리 배정된 1을 건너뛴 2부터 student_id에 배정된것.
문제도 인지했고 이유도 알았으니 auto를 사용하지 않고 identity를 사용하면 되겠다 싶었지만
이대로 끝내기도 아쉽고, 아니!! 이걸 갑자기 왜 바꿨는지 궁금해서
여러가지 문서, 블로그, 사이트를 뒤져봤다.
자동 키할당 방식에 대해서 조금만 더 학습하고 넘어가자
IDENTITY의 경우에는 AutoIncrement 기능을 제공하여
기본 키 값을 자동으로 생성하는 DBMS에서 사용된다.
주로 Mysql, PostgreSQL, SQL Server, DB2에서 사용하며
Transaction을 지원하는 쓰기 지연 방식이 동작하지 않는다는 특징이 있는데
아직 명확하게 이해하지 못한 부분이라 후에 다시 서술.
SEQUENCE의 경우에는 시퀀스란 순차적으로 증가하는 순번을 반환하는 데이터베이스 객체로
하이버네이트에게 여러 데이터베이스 사이에서의 뛰어난 이동성을 준다.
Sequence를 지원하는 Oracle, PostgreSQL, Db2, H2, MariaDB에서 주로 사용
TABLE의 경우에는 키 생성 Table을 사용하는데 key만을 위한 테이블을 생성한다.
이는 마치 Sequence타입과 유사한데 내부 동작방식이 같다. (흉내낸다고 봄)
다만 Sequence와 다른점은 한번 더 통신을 한다고함.
AUTO의 경우에는 선택한 DB를 따라 자동으로 IDENTITY, SEQUENCE, TABLE 중 선택한다.
키 생성 전략이 정해지지 않은 개발 초기 단계나 프로토타입 개발 시에 편리하게 사용가능.
Hibernate 5.0부터는 GenerationType AUTO를 사용하였을때
SEQUENCE를 지원하지 않는 DB라면 TABLE의 방식을 따른다!!!!@@!@!@!@
사실 이부분이 오늘 고민하고 배웠던 부분중에서 제일 중요했던 부분인데
기존에는 알아서 IDENTITY를 지정해주었는데 왜 TABLE로 바뀌었을까??
이걸 알아보기 위해서 Hibernate의 ORM 5.0 UserGuide를 살펴보았는데 (5.0부터 바뀐대서)
유저 가이드를 아무리 찾아봐도 Auto가 변경된다는 이야기는 있지만 이유는 적혀있지 않았다.
하지만 여러 자료들을 찾아보고 살펴본결과
https://db-engines.com/en/ranking_trend 사이트의 DB엔진 사용량 랭킹을 보았을때
미세하긴 하지만 Mysql에 비해서 Oracle의 사용량이 좀더 높은것을 볼수있고
Sequence타입을 지원하는 DB가 더 많은점, Sequence타입이 좀더 관리가 용이한점을 보았을때
Hibernate에서도 사용자들에게 발맞추어서 변경하지 않았을까 싶은 개인적인 생각이다.
라는 나의 생각도
https://stackoverflow.com/questions/26578313/how-do-i-create-a-sequence-in-mysql
스택 오버플로우에서 볼수 있듯이 다른사람들도 아니 왜 지원안하지? 어떻게 구현하지?
MariaDB를 사용하십쇼 Maria에서는 지원합니다. 이러고 있을정도로
Mysql만의 특징? 성격으로 남은듯하다....
강의를 들을 때 얼핏 듣기로는 mysql마음에 안들어서 나가서 만든게 MariaDB라니
이런 부분에서 의견충돌이 있었을까 싶기도 하다.
작은 트러블로 시작된 고민이고 궁금증이였지만
몇시간이고 찾아보고 정리해본 끝에
어느정도 원하던 결과를 얻은것 같아서 만족중이다.
사실 다른사람들이였으면 아 그냥 안되는구나 바꿔야지 하고 넘어갔을텐데
혼자서 너무 오랫동안 끌어안고 있었던것 같아서 조금 걱정되는부분도 있었다.
모르는 부분을 Deep하게 공부하는 것은 재미도있고 좋기도한데
사실 더 중요한 개념들조차 이해하지 못했음에도 다른데 시선이 팔린것 같기도하고
이렇게 모르는 부분들을 파고파고 또파는 Drilling을 하다보면
개발자들 사이에서 말하는 토끼굴에 빠진다는 상황이 닥칠것 같아서 걱정도 되고
배울 게 많다는점, 새로운게 끊임없다는점이 너무나도 매력적이지만
다른 방향에서 보면 정말 터무니없이 많거나 어렵거나 헤매는 상황이 오기도 하니
프로그래머 너무 어렵다!!!!!!!!!!!!!!
주요 참고 자료들
https://jake-seo-dev.tistory.com/72
https://velog.io/@gillog/JPA-기본-키-생성-전략IDENTITY-SEQUENCE-TABLE
https://coding-factory.tistory.com/420
https://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html