기본적으로 스프링 컨테이너의 객체가 Entity Manager, em의 컨텍스트의 접근하는 것은 트랜잭션 범위 내에서 가능하다.
트랜잭션이 종료되면 더 이상 엔티티에 접근할 수 없는데 어떻게 지연 로딩을 사용하는
로직들에서 에러가 발생하지 않는걸까?
지연로딩은 트랜잭션 시작 시점에서 엔티티를 불러오지 않고 실제 데이터에 접근하게 되는 시점에 엔티티를 불러옴
이는 지연 로딩을 사용할 수 있게 만들지만 Response Body나 Form에 데이터가 담겨
사용자에게 실제로 반환될 때까지 커넥션을 유지하기 때문에 만약 외부 API 호출에 의한 블로킹이 걸린다거나 하면 커넥션 풀이 모두 차버리는 문제가 발생할 수 있다.
org.hibernate.LazyInitializationException: could not initialize proxy [jpabook.jpashop.domain.Member#1] - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:169) ~[hibernate-core-5.3.17.Final.jar:5.3.17.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309) ~[hibernate-core-5.3.17.Final.jar:5.3.17.Final]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45) ~[hibernate-core-5.3.17.Final.jar:5.3.17.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.3.17.Final.jar:5.3.17.Final]
at jpabook.jpashop.domain.Member$HibernateProxy$X70B1PVb.getName(Unknown Source) ~[main/:na]
at jpabook.jpashop.api.OrderApiController.ordersV1(OrderApiController.java:35) ~[main/:na]
@GetMapping("/api/v1/orders")
public List<Order> ordersV1() {
List<Order> all = orderRepository.findAllByCriteria(new OrderSearch());
for (Order order : all) {
order.getMember().getName(); // OSIV : false에 따른 no session 에러 발생