작성
·
235
1
제가 이해한 바로는
Team team = new Team();
team.setName("TeamA");
entityManager.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
entityManager.persist(member);
// team.getMembers().add(member);
// entityManager.flush();
// entityManager.clear();
Team findTeam = entityManager.find(Team.class, team.getId());
List<Member> members = findTeam.getMembers();
for (Member m : members) {
System.out.println("member = " + m.getUsername());
}
(위의 코드는 강의에서 작성해주셨던 코드와 동일합니다)
제가 이해한 바로는
"flush, clear를 하지 않음으로써 그 상태의 영속성 컨텍스트에 등록된 Team과 Member 기준으로 members의 값을 가져오기 때문에
System.out.println("member = " + m.getUsername());
위 코드에 대한 출력이 되지 않는것으로 이해했습니다 ㅠㅠ!"
제가 이해한 바가 맞을까요 센세...?
이게 만약 맞다면 "추가적으로 "
flush 와 clear를 하는 과정에서
"원래 commit 시점에 쿼리가 발생하여 1차 캐시 혹은 DB에 값을 적재하는것이 정상이지만 flush 를 사용하는 시점에 해당과정을 즉시 실행하여 데이터를 적재시키고
다음으로 clear를 함으로써 비영속상태로 만들어 getMembers(); 시에 JOIN쿼리를 발생시켜 members와 관련된 데이터를 반영시킨다고 이해하였습니다."
마지막으로 "getMembers를 하는 과정에서 Member들을 가져오는 join 쿼리를 날리는 과정은 무조건 비영속 상태이어야만 하는지가 궁금합니다."
질문이 많았죠 센세... 항상 넘나 재밌게 잘 보고 있습니다~!!! JPA를 실무에서 사용한적이 없어서... 이런저런 궁금한점이 참 많습니당...
항상 감사합니다!!!!!
답변 1
1
안녕하세요. JuNu님
앞부분은 이해하신 내용이 맞습니다^^!
추가적으로 부분을 답변 드릴게요.
"원래 commit 시점에 쿼리가 발생하여 1차 캐시 혹은 DB에 값을 적재하는것이 정상이지만 flush 를 사용하는 시점에 해당과정을 즉시 실행하여 데이터를 적재시키고
-> 네 맞습니다.
다음으로 clear를 함으로써 비영속상태로 만들어 getMembers(); 시에 JOIN쿼리를 발생시켜 members와 관련된 데이터를 반영시킨다고 이해하였습니다."
-> clear를 하게되면 영속성 컨텍스트가 완전히 비어있게 됩니다. 이 상태에서 em.find(Team.class ..)을 호출하게 되면 DB에서 새로 Team 객체를 조회합니다. 그리고 이 Team 객체는 team.getMembers()를 호출하게 되면 연관된 Member들을 조회할 수 있게 됩니다.(지연 로딩이라고 하는데 뒤에서 학습합니다.) JPA가 연관관계를 보고 이런 것을 해주는 것이지요.
반면에 앞에서 직접 저장한 team은 members 컬렉션에 아무것도 넣지 않았기 때문에 데이터가 없었습니다.
마지막으로 "getMembers를 하는 과정에서 Member들을 가져오는 join 쿼리를 날리는 과정은 무조건 비영속 상태이어야만 하는지가 궁금합니다."
-> 앞부분의 설명을 보시면 이해가 되실거에요^^
감사합니다.
@Transactional은 준비중인 스프링 데이터 접근 기술에서 자세히 다룰 예정입니다.
우선은 @Transactional로 한번 검색해보시거나, 토비의 스프링을 보시면 도움이 되실거에요^^
갓.... 그저 저에게 빛입니다 ㅠㅠ...
이외의 추가적으로 질문드리자면... 제가 @Transactional 에 대한 이해가 없어서요...
해당 어노테이션에 대해서 공부를 하기 위해서는 추천해주실 영한님 강의가 있으신지 궁금합니다ㅠ!