• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

em.clear() 질문

24.04.22 00:32 작성 조회수 68

0

안녕하세요. 혼자 실습 중에 이해가 안가는 것이 있어 질문드립니다.

Member member = new Member(1L, "jiho");
em.persist(member); 

Member jiho = em.find(Member.class, 1L); 
em.clear(); 
Member jiho2 = em.find(Member.class, 1L); 

System.out.println(jiho == jiho2); 

tx.commit();

를 실행했을 때의 결과가

로 나옵니다.

false 출력 후에 commit() 호출로 쓰기 지연 저장소에 있던 insert sql문이 실행되야할 것 같은데,

실행되었다는 문구도 없고 DB에도 저장되어있지않습니다.

 

em.clear();가 1차캐시 뿐만 아니라 쓰기 지연 저장소에 있는 쿼리문들도 모두 지워버리는건가요?

답변 2

·

답변을 작성해보세요.

1

안녕하세요. 김지호님

생각하신 내용이 맞습니다.

감사합니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.22

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

김지호님의 질문에 대해 찾아본 결과, em.clear();의 작동 방식과 관련하여 em.flush()em.clear()에 대한 이해가 도움이 될 것 같습니다. em.clear(); 호출 이후에 em.find()를 사용했을 때의 동작이 궁금하신 것으로 보입니다.

먼저, em.clear();는 영속성 컨텍스트를 완전히 초기화하는 작업을 수행합니다. 이는 모든 관리되고 있는 엔티티를 준영속 상태로 만드는 과정이며, 1차 캐시 역시 초기화됩니다. 하지만, 쓰기 지연 저장소에 있는 쿼리들이 이 때 바로 실행되거나 삭제되진 않습니다. 명시적으로 em.flush()를 호출하지 않는 이상, 트랜잭션 커밋 시점에 쓰기 지연 SQL 저장소의 쿼리가 데이터베이스에 반영됩니다.

이와 관련된 좀 더 깊이 있는 설명은 아래 인프런 내의 질문&답변 링크에서 찾을 수 있습니다:

다음으로, 김지호님의 경우에 false가 출력되고, commit() 호출 이후에도 DB에 저장되지 않는 현상에 대해서는, em.clear(); 호출 이후, 같은 엔티티에 대한 find 연산이 두 번 이루어진 경우임에도 불구하고 두 객체가 다르다(false)로 나타난 것은 영속성 컨텍스트가 초기화된 후 find 호출 시 새로운 엔티티 조회가 일어났기 때문입니다.

하지만, em.flush();가 명시적으로 호출되지 않았고, em.clear();에 의해 영속성 컨텍스트가 초기화된 상태라면, 이어진 작업에 따라 commit() 시 최종적으로 데이터베이스에 반영되는 내용이 달라질 수 있습니다. em.clear(); 호출 이후 변경사항에 대해서는 flush()commit()을 통해 데이터베이스 반영 여부가 달라질 수 있는 사항입니다.

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