• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

em.clear() , em.close()

24.01.10 23:24 작성 조회수 126

0


[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
Team team = new Team();
team.setName("TeamA");
em.persist(team); em.flush();
em.clear(); 1차 캐시 비우기
em.close(); 영속성 컨텍스트 종료
로 알고 있는데
System.out.println(" =============== ");
System.out.println("team = " + team.getId());
System.out.println(" =============== ");

이 team.getId() 값이 null이 아니라 해당 id 값이 출력될 수 있는 이유가 persist 할떄 team id 필드에 초기화 되서 인건가요?

답변 2

·

답변을 작성해보세요.

0

Kim DongKyun님의 프로필

Kim DongKyun

2024.01.11

안녕하세요 질문자님!

 

먼저, persist() 를 호출했을 때 어떤 일이 일어나는지에 대한 간략한 설명은

 

[save 호출 시 일어나는 일]

 

위 링크를 참고 해 주세요! (save() 매서드에서 em.persist() 를 호출한답니다)

 

링크를 간단히 요약하면 엔티티의 아이디를 자동 생성 방식으로 설정했을 시(@GenerateValue), 엔티티의 아이디를 자동으로 생성 해 주기 위해서 DB에서 값을 가져와야 하는데요, 이 때 가져온 값으로 자바의 객체(엔티티인 Team) 아이디를 자바의 리플렉션을 사용해서 채워넣게 됩니다.

 

즉, persist() 를 호출 한 순간 영속성 컨텍스트와 관계 없이 자바의 객체는 id 값을 가지게 됩니다.

 

[리플렉션 설명]

 

도움이 되었으면 좋겠습니다. 감사합니다

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.01.10

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

질문자님께서는 em.persist(team) 후에 em.flush(), em.clear(), em.close()를 호출하고 나서 team.getId()를 호출했을 때 왜 null이 아니라 실제 ID 값이 출력되는지 궁금해 하시는군요.

em.persist(team) 호출 시, JPA는 team 엔티티를 영속 상태로 만듭니다. 이때, JPA 구현체는 ID 생성 전략에 따라 team의 ID 값을 설정합니다. 예를 들어, ID가 자동 생성(auto-increment)되는 방식으로 설정되어 있다면, 이 시점에서 JPA는 데이터베이스에 맞게 초기화된 ID 값을 가질 수 있습니다.

em.flush()는 영속성 컨텍스트에 있는 쓰기 지연 SQL 저장소에 쌓여있는 쿼리들을 데이터베이스에 보내 실행하지만, 영속성 컨텍스트를 비우지는 않습니다. 따라서 flush 이후에 team.getId()를 호출하면 이미 설정된 ID를 가져올 수 있습니다.

em.clear()를 호출하면 영속성 컨텍스트를 비우게 되며, 모든 영속 상태의 엔티티들이 준영속 상태가 됩니다. 그러나 이미 persist()를 통해 식별자가 할당된 엔티티는 그 식별자 값을 유지하게 됩니다. 그렇기 때문에 clear 이후에도 team.getId()null이 아닌 값이 반환됩니다.

단, em.close()는 영속성 컨텍스트를 종료하는 명령입니다. 하지만 엔티티 객체 자체(team)와 그 식별자 값(team.getId())은 Java 객체이므로, 영속성 컨텍스트가 닫혀도 해당 객체의 참조를 통해 ID 값을 가져올 수 있습니다.

이해를 돕기 위해 아래와 같은 기존 답변 링크를 추천해 드립니다:

교육 과정의 실습 예제에서 em.persist() 후에 em.flush()em.clear()를 진행하는 것은 보통 엔티티의 상태 변화를 데이터베이스에 즉시 반영하고, 영속성 컨텍스트를 초기화하기 위한 목적으로 사용됩니다. 데이터베이스에 즉시 반영되면, 이후에 수행되는 조회 등의 연산에서 데이터베이스의 최신 상태를 반영할 수 있게 됩니다.

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