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

컴퓨터공부하자님의 프로필 이미지

작성한 질문수

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

양방향 연관관계와 연관관계의 주인 2 - 주의점, 정리

같은 트렌젝션 안에서 mappedBy 참조의 주의점에 대하여 질문드립니다!

해결된 질문

21.08.19 23:40 작성

·

196

1

실습을 해보다가 em의 움직임에 궁금한 점이 생겨서 질문드립니다. 실습 부분을 제가 임의로 단순화 시켜서 조금 다른 점이 있을 수도 있습니다.

아래와 같은 두 가지 Entity가 있다고 가정합니다.

제가 성공하고 싶은 로직은 아래와 같은 로직입니다.

결론부터 말씀드리면 '성공하고 싶은 로직' 즉 mappedBy로 참조한 student entity에 접근해서 Id를 출력하기 위해서는 필수1, 필수2, 필수3이 모두 필요했습니다. 

처음 저는 em.flush() (필수1)로 DB에 반영만 해주면, 필수2, 필수3 필요없이 곧바로 mappedBy로 필드를 사용해서 Student Entity를 호출할 수 있을 줄 알았습니다. DB에 반영하기만 하면 em이 알아서 전부 관리해 줄 줄 알았던 것입니다. 처음에는 필수1 만 사용해서 A로직으로 구현했었고 studentList에는 어떤 element도 들어있지 않은 empty 컬렉션이 반환되었습니다. 

그런데 실험을 해보니 필수1과 필수2를 통해 DB에 영속성 컨텐스트 내용을 반영한 뒤 초기화까지 해줘야 했습니다. 그리고 그대로 newShcool_A를 사용하면 안 되었고 em.find()(필수3)로 다시 DB에서 가져온 newShcool_B를 사용해야 mappedby 필드로 Student Entity들을 참조할 수 있었습니다. 

결론적으로는 하나의 트렌젝션에서 mappedBy 필드를 사용할 때는 주의해야 겠다는 교훈을 얻긴 했지만 두 가지 궁금증이 생겼습니다.

<질문1> 제가 위에서 실험해본 대로 EntityManager가 동작하는 것이 맞는지요? 제가 실험을 엉뚱하게 했을 수도 있을 것 같아서요.

<질문2> 제가 처음 생각한대로 DB에 영속성 컨텍스트를 반영해주기만 하면 <필수1만 사용> 되지 않는 이유가 무엇일까요? 굳이 영속성 컨텍스트를 초기화하고 em.find()로 다시 DB 데이터를 가지고 와야 하는 이유를 정확히 모르겠습니다. 프록시를 사용해야 하니까? 라고 막연하게 생각하고 있지만 정확한 원리가 궁금합니다.

답변 1

1

김영한님의 프로필 이미지
김영한
지식공유자

2021. 08. 21. 22:40

안녕하세요. 컴퓨터공부하자님

이런 문제 때문에 원칙적으로 연관관계를 설정할 때는 양방향 연관관계를 설정해주어야 합니다.

JPA에 객체를 저장할 때는 해당 객체가 그대로 저장되기 때문에 조회 시점에도 같은 객체가 조회합니다.

내가 저장한 객체가 아닌 처음부터 조회한 객체는 mappedBy에 의해 추가 조회기능이 가능합니다.

감사합니다.