인프런 커뮤니티 질문&답변

김민지님의 프로필 이미지

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

일대다 [1:N]

양방향 매핑관계- 양쪽에 값을 설정해주어야한다

작성

·

211

0

 
36번째줄에 findteam.getmembers을 찾아와도 없는 이유가 아직 디비에 쿼리를 날린건 아니여서 (영속성컨텍스트에만있어서) 그런건가요? 그니까 디비에 쿼리를 날려야 member의 team이 team으로 세팅된걸보고..? team의 member도 알아서 세팅을 해주는건가요?
 
그리고 아래의 말이 맞나요?
 
저 여기서 em.persist를 하면 
1. 영속성 컨텍스트에 저장한다,
2. sql저장소에 쿼리가 쌓이고 커밋시 db에 보낸다
인건가요?
근데 find를하면 일단 영속성 컨텍스트에서 찾으니까 값을 찾아올수있는거구요
 

답변 2

1

1번은 강의 뒷부분을 더 보고 이해가 되었습니다. 감사합니다


2번의 경우는 바로 DB로 전송되는 이유가 어떻게 되나요?? 아이덴티티 전략이 persist를 하면 바로 DB에 다녀오고 시퀀스 전략은 id값을 미리 생성(ex 50개)해서 할당하는 것 아닌가요?? 강의를 다 보긴 했는데 제가 아예 잘못 이해하고 있으면 어떤 회차를 다시 봐야될지 알려주시면 감사하겠습니다!

안녕하세요 code-tree님!

아이디 생성 전략이 sequence 인 경우 code-tree님 말씀이 맞습니다.

제가 말씀드린 내용은 identity 방식일 경우에만 해당하는 내용입니다.

sequence의 경우 한번에 여러개의 아이디를 획득, 이 아이디가 모두 소진되기 전까진 

데이터베이스에 직접 다녀오지 않습니다.

 

감사합니다!!

1

안녕하세요, 김민지 님! 공식 서포터즈 codesweaver 입니다.

JPA에는 Lazy Loading 이라고 하는 최적화기술을 제공합니다.

이는 웹에서 많이 사용하는 개념인데, 아직 쓰지 않을 리소스를 굳이 로드하지 말자는 개념입니다.

 

비유를 하자면 당장 만원만 필요한데 통장에 있는 잔고를 몽땅 빼올 필요가 없다는 겁니다. (잔고가 만원이면.... 몽땅 빼야겠네요)

 

만약 모든 코드를 싹 지우고 em.find(Team.class, 1); 로 조회하는 경우를 가정하면 Team의 모든 값들을 채운 객체를 반환합니다. 하지만 List<Member>는 지금 당장 사용할건지 아닌지 JPA 입장에서 알 수 없습니다. (며느리도 모르고, 개발자만 압니다) 그래서 Member에 대한 내용은 제쳐두고 나머지 Team 객체 정보만 조회해서 반환합니다. 

 

이후 Member를 실제로 사용하는 시점이 되면 그제서야 DB에 다시 가서 혹은 영속성 컨텍스트에 있다면 그것을 찾아서 가져옵니다. 이런 방식을 Lazy Loading이라고 합니다.

 

em.persist()를 한 경우엔 즉시 쿼리를 날립니다.

그래서 데이터를 insert하고 그로 인해 생성한 아이디 값을 이용해 영속성 컨텍스트에 보관합니다.

그래서 다음의 코드를 보면,

Team team = new Team()

team.setName("팀1");

em.persist(team);

-- 이 뒤에

System.out.println(team.getId());

-- 아이디를 조회하면 정상적으로 team의 아이디가 조회됩니다. persist 이후에 즉시 디비에 갔다오기 때문입니다.

 


감사합니다.

안녕하세요! 이해가 안 되는 부분이 있어 질문 좀 드리겠습니다.. ㅠㅠ

1. Team에서 List<Member>에 조회가 안 되는 이유는 아직 member가 DB에 Insert가 안 된 상태라서 조회가 안 되는 것 아닌가요??

2. em.persist(member)를 하면 
1) 1차 캐시에 member 객체를 보관
2) 쓰기 지연 SQL 저장소에 INSERT SQL을 보관
3) 시퀀스 전략에 의해 Id(Key)값 할당
이렇게 되어있다가 flush 또는 트랜젝션 커밋, JPQL 실행하는 시점에 DB에 Insert가 되는거 아닌가요?

1. LazyLoading 설정이라면, member가 데이터베이스에 있는 상태라 하더라도, 엔티티매니저로 team을 찾은 뒤 List<Member>는 빈 콜렉션을 참조하게 됩니다. List<Member>를 구체적으로 사용하는 순간 데이터베이스에서 Member 엔티티를 조회합니다.

2. persist는 말씀하신 과정에서 2)의 과정이 포함되지 않습니다. 즉시 데이터베이스에 다녀오게 됩니다. 그리고 데이터베이스에서 획득한 key를 아이디로 갖게 됩니다.

 

감사합니다.