본문 바로가기
웹개발/Springboot

open-in-view

by HoPpangg 2021. 7. 18.
SMALL

스프링 서버를 실행시키면 항상 WARN이 하나씩 뜨는데 이게 왜 뜨는지 궁금해졌습니다. 옆에 내용을 읽어보니 open-in-view is enabled by defalut 라고 나와있습니다. open-in-view 부터 뭔지 알아야할 것 같습니다.

 

open-in-view 는 쉽게 말하면 view가 반환되기까지 session을 유지하는지에 대한 여부입니다. 

open-in-view is enabled by default 라는 뜻은 default 값으로 적용이 된다는 것으로 볼 수 있습니다.

opein-in-view 의 default 값은 view 까지 session이 유지되는 것입니다. Controller에서 session이 끊기지 않고 lazy loading이 되는 것 입니다.

그렇다면 반대로 session을 끊어낼 수도 있겠죠? Controller 진입 직전 session을 끊는데 이는 영속성 컨텍스트를 돌아서 controller로 다시 돌아오기 직전 session이 끊긴다는 것입니다.

최초 요청 -> Controller -> Repository -> 영속성 컨텍스트(필요한 데이터가 없으므로) -> DB -> 영속성 컨텍스트 -> Repository -> Controller -> 응답

 

재요청 -> Controller -> Repository -> 영속성 컨텍스트(필요한 데이터가 있음) -> Repository -> Controller -> 응답 

 

재요청 시 필요한 데이터를 가지러가기 위해 DB까지 가지 않고 영속성 컨텍스트에서 가지고오게 됩니다.

Lazy Loading 도 영속성 컨텍스트에서 결정이 됩니다.

 

따라서 위의 WARN을 없애고 싶다면 open-in-view를 true/false로 세팅해주면 됩니다.

properties.yml 파일에서 설정해줄 수 있습니다.

WARN이 없어진 것을 볼 수 있습니다.

 

세션이 일찍 끊기면 다른 사람들이 더 많이 들어올 수 있습니다. 

그렇다면 open-in-view를 false 로 놓는다면 controller 진입 직전에 session이 끊겨버리게 됩니다.

 

open-in-view를 false로 놓고 user 테이블에서 fetch 값을 LAZY로 설정하고 서버를 실행시키면 어떻게 될까요?

lazy loading일 때는 post 컬렉션을 다시 select 해야하는데 open-in-view가 false이기때문에 session이 끊겨 에러가 납니다.

에러 내용에도 no Session을 볼 수 있습니다.

 

그렇다면 fetch 값을 EAGER로 설정하고 다시 실행시켜봅니다.

잘 실행됩니다.

콘솔창에서도 조인하는 것을 볼 수 있습니다.

더보기

Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.password as password4_1_0_, user0_.userid as userid5_1_0_, posts1_.user_id as user_id4_0_1_, posts1_.id as id1_0_1_, posts1_.id as id1_0_2_, posts1_.content as content2_0_2_, posts1_.title as title3_0_2_, posts1_.user_id as user_id4_0_2_ from user user0_ left outer join post posts1_ on user0_.id=posts1_.user_id where user0_.id=?

 

다시 open-in-view를 false로 두고 user의 fetch값과 post의 fetch 값을 모두 default로 해주고 각 모델에서 toString 메서드를 만들어서 객체를 프린트하는 코드를 추가해보겠습니다.

에러가 납니다! 이때 user의 fetch 값을 eager로 설정해주거나 open-in-view를  true 로 바꾸어주어야 합니다.

 

fetch 값을 eager로 설정하고 실행해보면

StackOverflowError가 발생합니다. 

이유는 user의 toString 메서드에서 post를, post의 toString 메서드에서 user를 재귀호출을 무한적으로 해서 메모리가 꽉 차기 때문입니다. 

이를 해결하기 위해서 post나 user 중 한쪽의 toString에서 user나 post를 지워주면 재귀호출을 하지 않기 때문에 문제를 해결할 수 있습니다.

잘 작동하는 것을 볼 수 있습니다.

 

만약 fetch 값을 Lazy로 하고 싶다면 open-in-view를 true로 설정하면 됩니다.

728x90
LIST

댓글