Java, Spring/스프링부트와 JPA 활용 2

3-1. 간단주문조회 V1 : 엔티티를 직접 노출

app0a 2022. 9. 9. 10:34

결국 주문을 조회 하면 배송정보+회원은 딸려온다.

 

정말 간단하게 만들어보자. 이렇게 되면 Order 뿌리려 갔는데 Member가 있고 그 Member를 뿌리려 가면 또 Order가 있다. 

-> 무한 루프 -> 객체를 JSON으로 만드는 JACKSON 입장에서는 무한루프를 돌며 객체를뽑아낸다.

끝이 안남.

양방향이면 반대편에서 @JsonIgnore 해줘야한다. (여기선 Order와 양방향인 Member, OrderItem, Delivery에서 Order 필드를 @JsonIgnore 해줌.)

 

여기서 두 번째 문제 발생!

지연로딩 : DB에서 안가져옴.

여기서도 보면 Member가 지연로딩이므로 Order를 가져올 때 아예 DB에서 Member를 안가져옴.

하이버네이트가 Member를 상송한 프록시객체를 만들어서 넣어둠. (ByteBuddy 라이브러리)
실제론 이렇게 들어가있음.

-> Member의 프록시객체를 넣어두고 Member객체에 접근 할 때 그 때 DB에 쿼리를 날려서 값을 가져와 채워줌 (프록시를 초기화 한다. 라고함)

 

이미 아는 내용.

 

-> But JACKSON 라이브러리는 프록시객체를 모름. (Order -> Member 뽑아야지 하는데 Member객체가 아니라 프록시객체가 들어있다.)

 

-> LAZY로딩일 때는 JACKSON에게 그냥 그 값 뿌리지 말라고 해줄 수 있음.

 

-> HIBERNATE5MODULE

버전 안적어줘도 스프링부트가 관리

 

수동 빈 등록
드디어 이렇게 나온다.

Member, OrderItems, Delivery 는 모두 지연로딩 이므로 null 들어가 있음. (hibernate5module 이 LAZY 로딩을 무시)

 

But 강제로 LAZY 다 끌고 오는 방법이 있다.

 

바로 이렇게 LAZY를 다 끌고 온다. 

order.getMember() 까지는 프록시 객체, .getName()로 LAZY객체에 접근하는 순간 실제 객체 가져와서 넣어둠.(이때서야 DB에 Member 가져오는 쿼리 날라감. ) -> 다 아는 내용. 

 

이렇게 출력. orderItems 는 null 맞고, 이렇게 배열로 출력하는건 안좋다. -> 전 강의에서 배움.

 

 

 

===== 사실 지금까지의 과정은 애초에 할 필요도 없는 과정 : 엔티티를 외부에 노출하지 말라했다.

= 엔티티 바뀌면 API스펙이 다 바뀐다.

-> 꼭 필요한 정보만 API에 노출하자.

 

 

 

이번 강의의 최고 중요점 :

EAGER 로 하면 항상 다 끌어오므로(필요없어도) 성능 문제 -> 성능최적화 할 수 있는 여지가 줄어든다.