작성
·
401
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)
[질문 내용]
이전 강의에서 strategy = IDENTITY 일때만 persist 시점에 insert 쿼리가 나가서 pk 값을 얻을 수 있다고 하셨는데 지금 상태는 @GeneratedValue 디폴트값(auto) 인데 어떻게 pk 값을 얻을 수 있는건가요??
답변 1
4
안녕하세요. ewgregerg c님, 공식 서포터즈 y2gcoder입니다.
이전 강의에서 strategy = IDENTITY 일때만 persist 시점에 insert 쿼리가 나가서 pk 값을 얻을 수 있다고 하셨는데
=> 이 부분을 잘못 이해하신 것 같습니다. @GeneratedValue 는 기본 키 자동으로 생성해주는 애노테이션입니다. 전략을 다르게 가져가면 해당 기본 키를 자동으로 생성하는 방법만 달라질 뿐입니다. IDENTITY 전략은 데이터베이스에 기본키 생성을 위임합니다. 그래서 실제로 DB에 Insert 문을 날리기 전에 DB로부터 pk를 조회하여 해당 pk를 포함하여 insert를 날리게 됩니다.
그리고 중요하게 기억하셔야 할 점은 JPA 엔티티들은 기본키를 바탕으로 엔티티를 식별하기 때문에 영속 상태가 되기 위해서는 기본 키가 있어야 합니다.
그래서 결국 영속 상태가 되었다는 말은 해당 엔티티가 기본키를 갖고 있다는 말과 동일하게 보셔도 됩니다.
한편 H2 DB는 기본키 생성전략을 AUTO로 주면, sequence 전략을 채택합니다. (섹션 4의 기본 키 매핑 강의를 참고해주세요!)
이러한 지식을 바탕으로
Team team = new Team();
team.setName("TeamA");
em.persist(team);
System.out.println("team id = "+team.getId());
Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
강의에서 나왔던 코드에 자그마한 프린트문을 추가해서 실행해보겠습니다!
위가 콘솔에서 실행 결과에 대한 로그입니다.
잘 보시면 먼저 ddl-auto 옵션에 의해 Member 테이블과 Team 테이블을 생성하는 모습을 보실 수 있습니다.
그 후
call next value for hibernate_sequence
이런 쿼리가 먼저 나간 것을 아실 수 있습니다. 시퀀스 전략이기 때문에 Team과 Member 엔티티를 영속상태로 만들기 전에 DB로부터 시퀀스를 가져오는 쿼리입니다!
그래서 제가 만들었던 print 문에 team의 id가 제대로 찍히고 있는 모습을 보실 수 있습니다!
그 후에 Member도 영속상태로 만들기 위해 한 번 더 sequence를 불러오고! 마지막에 트랜잭션 커밋 때 모아놨던 쓰기지연SQL 저장소에 있는 쿼리를 전부 DB에 날려주는 모습입니다 :)
감사합니다.
상세한 설명 감사합니다!