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

junil jeong님의 프로필 이미지
junil jeong

작성한 질문수

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

양방향 연관관계와 연관관계의 주인 1- 기본

이상한게 있습니다..

작성

·

29

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예

[질문 내용]
여기에 질문 내용을 남겨주세요.

 

Team team = new Team();
        team.setTeamNm("Team");
        em.persist(team);
        
        Members members = new Members();
        members.setName("good");
        members.setHelloTeam(team);
        em.persist(members);
  
        em.flush();
        em.clear();

        Members finMembers = em.find(Members.class, members.getId()); 
        List<Members> result = finMembers.getHelloTeam().getMembers();
        
        System.out.println("aaaaaaaaaaaaaaaaaaaa="+result.size());

뭔가 이상해요
em.flush(); em.clear(); 을 안쓰면

finMembers까지는 null 이 아닌데
results 까지는 null입니다. 왜 이런거예요
???

답변 2

0

안녕하세요. junil jeong님, 공식 서포터즈 y2gcoder입니다.

양방향 연관관계 이기 때문에 발생하는 문제를 말씀하시는 것 같습니다!

기본적으로 영속성 컨텍스트를 초기화해주지 않으면 이미 영속성 컨텍스트에 있는 객체를 사용하게 됩니다!

Team team = new Team();
team.setTeamNm("Team");
em.persist(team);
        
Members members = new Members();
members.setName("good");
members.setHelloTeam(team);
em.persist(members);

이 때 연관관계 편의 메서드를 통해서 설정할 때 setHelloTeam() 내부에서 team의 members에 해당 members를 할당하는 로직도 추가해주셨을까요? 그렇지 않다면 영속성 컨텍스트 초기화 후 DB에서 다시 조회해왔을 때와 불일치가 발생할 수 있습니다!

자세한 이유는 해당 챕터를 전부 수강하시고 나면 이해가 되실 거라 생각합니다!

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

junil jeong님이 작성한 코드에서 관찰된 현상은 JPA의 영속성 컨텍스트와 관련이 있습니다. em.flush()em.clear()를 사용하지 않으면 모든 데이터가 영속성 컨텍스트에 남아 있게 됩니다. 이 경우에는 em.find()를 통해 조회된 finMembers도 영속성 컨텍스트 내에서 관리되므로, 연관된 팀 정보가 이미 메모리에 있을 가능성이 커집니다.

그러나 em.flush()em.clear()를 호출하게 되면 현재 영속성 컨텍스트의 상태가 데이터베이스에 반영되고, 영속성 컨텍스트가 초기화됩니다. 이로 인해 엔티티를 다시 조회할 때 영속성 컨텍스트 내에 캐시된 엔티티가 없기 때문에 데이터베이스로부터 새롭게 로드되어야 합니다.

이때 finMembers.getHelloTeam().getMembers()에서 getMembers()가 호출되면 연관된 Members 리스트가 초기화되지 않아 null이나 빈 리스트를 반환할 수 있습니다. 특히 컬렉션의 지연 로딩(Lazy Loading) 설정이 되어 있다면 문제가 발생할 수 있습니다. 지연 로딩은 해당 컬렉션의 실제 사용 시점에 데이터베이스에서 데이터를 가져오도록 설정할 수 있습니다.

이 현상을 피하기 위해, 연관 컬렉션을 즉시 로딩(Eager Loading)으로 설정하거나, em.find() 호출 전 관련 데이터를 가져오기 위한 적절한 JPQL 쿼리를 활용하시는 것이 좋습니다.

추가적으로 다른 학습자의 유사한 질문과 답변을 참조하시면 도움이 될 수 있습니다:
- 페치 조인과 관련된 문제
- 지연 로딩과 즉시 로딩의 차이에 관한 질문

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

junil jeong님의 프로필 이미지
junil jeong

작성한 질문수

질문하기