목차
- LAZYloading의 개념
- 실습
- LAZY
- EAGER
- Open-in-view
LAZYloading의 개념
oneToMany의 default 설정값은 LAZY입니다.
*
messageConverter 동작원리를 알아야 합니다.
User-> 객체 -> JSON으로 반환
*
Lazy Loading
oneToMany로 만약 양방향 Mapping으로 컬렉션에 있는 데이터도
Getter로 다 들고 오게 되면 느려지기 때문에
(많은 일을 하게 됨, 즉, 쓸데없이 들고 와야 하는 경우도 있음)
Lazy Loading을 사용해서 컬렉션은 Getter로 불러오지 않게 합니다.
그렇게 되면 Getter를 사용하지 않은 상태는 데이터를 들고 오지 않은 상태입니다.
그 상태에서 Getter를 사용하게 되면 데이터를 불러오는 상태가 됩니다.
MessageConverter가 모두 다 때려버립니다.
(Json으로 바꾼다)
반면,
@ignoreproperteis(때리지 마 설정)을 사용하여
ViewResolver로 내가 때리는 걸 제어할 수 있습니다.
(컨트롤러의 속성)
*
여기서 때린다는 표현은 dispatcher가 그 메서드를 실행하는 것을 표현한 것
*
세션
Object일 때 join으로 다 들고 옵니다.
그러나 컬렉션이면 다 들고 오지 않습니다.
(오직 getter를 때려야 한다)
크기를 알 수 없는 것들은-> reference -> 모두 주소를 가져옵니다.
가령 python에서 변수를 선언할 때 int, String 값을 넣지 않는데, 이게 바로 크기를 알 수 없다는 것입니다.
그렇기 때문에 C언어에 비해서 python이 느린 것입니다.
실습
String으로 반환하면서
join을 하지 않고 바로 user로 만들어 옵니다.
-> 여기서 userEntity에는 posts항목이 들어가 있지 않습니다.
원래라면 들고 와야 하는데 들고 오지 않습니다.
(posts가 컬렉션으로 되어 있기 때문에)
User
{
user id..
user password..
<posts>
}
posts는 들고 오지 않습니다.
바로 컬렉션 형태로 되어있기 때문입니다.
JsonIgnoreProperties 설정으로 MessageConverter가 설정값을 넣어
설정값을 호출할지 안 할지 우리가 설정할 수 있습니다.
(--> 이거 무시해라 이런 뜻)
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_.username as username5_1_0_ from user user0_ where user0_.id=?
-> join 없이 테이블이 합쳐져서 반환됩니다
즉, posts값은 어디에도 보이지 않습니다.
위에서 @JsonIgnoreProperties로 user속성을 들고 오지 말라고 해서 그렇습니다.
또한 title도 보이지 않습니다.
(posts안의 속성이기 때문에, user속성도 아마 posts안에 있는 user를 말하는 것 같습니다)
*
Mapping이 되어야 하는데 LAZY이고 open-in-view가 false라서 그렇습니다.
*
반면에 Post의 객체에서 postEntity로 바로 반환받아보면 Join 하여서 가지고 옵니다.
Hibernate: select post0_.id as id1_0_0_,post0_.content as content2_0_0_, post0_.title as title3_0_0_, post0_.user_id as user_id4_0_0_, user1_.id as id1_1_1_, user1_.address as address2_1_1_, user1_.email as email3_1_1_, user1_.password as password4_1_1_, user1_.username as username5_1_1_ from post post0_ left outer join user user1_ on post0_.user_id =user1_.id where post0_.id=?
그러나
fetchType을 추가해서 LAZY로 설정해두면
join 없이 select만 합니다.
Hibernate: select post0_.id as id1_0_0_, post0_.content as content2_0_0_, post0_.title as title3_0_0_, post0_.user_id as user_id4_0_0_ from post post0_ where post0_.id=?
위를 보면 Post의 전략을 바꾼 것인데 전과 다르게 DB에서 데이터를 가져오게 됩니다.
여기서 이해해야 할 것은
우리가 컬렉션같이 안의 객체를 다 들고 오지 못하는 것들은
fetchType의 전략을 설정해서 join으로 한 번에 들고 올지
select를 여러 번 써서 들고 올지 우리가 결정할 수 있다는 것입니다.
User에서의 FetchType 전략
LAZY
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_.username as username5_1_0_ from user user0_ where user0_.id=?
EAGER
Hibernate: select user0_.id as id1_1_0_, user0_.address as address2_1_0_, user0_.email as email3_1_0_, user0_.passwordas password4_1_0_, user0_.username as username5_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_ fromuser user0_ left outer join post posts1_ on user0_.id=posts1_.user_id where user0_.id=?
POST 전략 추가
Open-in-view
Spring.jpa.open-in-view은 LAZY LOADING을 위해서 만들었습니다.
(Session을 View 단 까지 끌고 가는 것)
Session은 Controller 열리기 전에 열립니다.
전통적인 Spring프레임 레거시에서는 세션이 컨트롤러 진입 직전에 끊겼다고 합니다.
세션을 빨리 닫으면 좋습니다.
서버가 더 많이 다른 클라이언트를 받을 수 있기 때문이죠.
위와 같은 최적화를 통해서 비용을 절감할 수 있습니다!
보통은 Session까지 끌고 갈 필요 없기 때문에
open-in-view의 설정값이
default 값으로 false로 되어있습니다.
open-in-view 실습
spring.jpa.open-in-view 오류가 발생하면
true로 값을 변경하면 뜨지 않습니다.
바로 생명주기를 늘려 우리가 기본적으로 설정된 값이 아니라
새롭게 설정을 해놓았기 때문에
WARN에서 바뀐 것입니다.
open-in-view 오류
posts 요청할 때 LAZY LOADING 때문에 세션이 살아있지 않은 상태에서 세션을 찾아야 하기 때문에 오류가 발생한다.
JPA Mapping 무한 참조오류
ToString에서 여러 번 반복 무한 참조할 경우
stack-overflow 오류 메시지가 뜬다.
'BackEnd > Spring' 카테고리의 다른 글
[Spring][13]API Practice[API 실습, test] (0) | 2021.07.11 |
---|---|
[Spring][12]API 활용하기 (0) | 2021.07.10 |
[Spring][10]ORM, JPA oneToMany[양방향 Mapping 실습] (0) | 2021.07.08 |
[Spring][9]RDB, Object Relationship Mapping in Spring[관계형 데이터베이스, ORM] (0) | 2021.07.07 |
[Spring][8]Login Practice[로그인 실습] (0) | 2021.07.04 |