프록시

엔티티를 조회할 때 연관된 엔티티들이 항상 사용되는 것은 아닙니다. 연관관계의 엔티티는 비즈니스 로직에 따라 사용될 때도 있지만 그렇지 않을 때도 있죠. 실제 사용하다보면 유저의 선택이나, 특정 상황에 따라 연관관계로 맺어진 정보들이 전혀 필요 없을때가 많습니다.
JPA는 굳이 필요없는 DB 조회를 줄이면서 성능을 최적화한다고 말씀드렸죠? 이런 문제를 해결하려고 엔티티가 실제 사용될 때까지 데이터베이스 조회를 지연하는 방법을 제공하는데 이것을 지연 로딩이라 합니다. 그런데 지연 로딩 기능을 사용하려면 실제 엔티티 객체 대상에 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데 이것을 프록시 객체라고 합니다.
즉시로딩과 지연로딩?
프록시가 막아주니까 가능한 기술이라고 보시면 될 것 같습니다!
즉시 로딩 : 엔티티를 조회할 때 연관된 엔티티도 함께 조회합니다. @ManyToOne(fetch = FetchType.EAGER)
지연 로딩 : 연관된 엔티티를 실제 사용할 때 조회한다.설정 방법 : @ManyToOne(getch = FetchType.LAZY)
간단하게만 설명하자면, 기본적으로 “즉시로딩”은 연관된 엔티티를 조인해서 다 긁어와버리는 것이고, ”지연로딩”은 실제로 가짜 객체를 이용하면, 그때 별도의 쿼리가 나간다고 생각하시면 될 것 같습니다.
하지만 즉시로딩은, 처음부터 모든 테이블에 조인을 걸어버리고 별도로 쿼리가 나가는 경우가 생기기에, 연관관계가 많고 복잡할수록 비용이 기하급수적으로 늘어나기에, 정확하게 이해하고 필요한 상황이 아니라면, 가급적으로 모두 지연로딩을 걸어두는게 일반적이기는 합니다. 쓸지 안쓸지 모르는데, 비용은 가장 많이 드는 작업일 수 있거든요!
기본값은 아래와 같긴 합니다.
@ManyToOne, @OneToOne: 즉시 로딩(FetchType.EAGER)
@OneToMany, @ManyToMany: 지연 로딩(FetchType.LAZY)
그렇다면 굳이 필요가 없다면, 앞으로 코딩 하실 때 @ManyToOne(FetchType.Lazy)로 걸어주시면 좋겠죠?
영속성 전이?
- 마지막으로 궁금한건 영속성 전이만 남은것 같네요예를들어 유저테이블과 메모 테이블이 있는데, 영속화한 유저객체가 있으면, 메모 테이블도 같이 영속화되어 같이 관리되는 것을 영속성 전이라고 합니다.지금은 CASCADE라는 옵션이 있다정도만 이해하시고, 나중에 실제 회원탈퇴라던지 이러한 로직을 구현 할 때 더 생각해보시면 좋을 것 같습니다. 설정은 아래와 같이 설정합니다!
- 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이기능을 사용하면 됩니다. JPA는 cascade 옵션으로 영속성 전이를 제공합니다.
'TIL' 카테고리의 다른 글
| [WIL] 2022.12.12~12.16 (0) | 2022.12.18 |
|---|---|
| 2022.12.16 MySelectShop (0) | 2022.12.18 |
| 2022.12.14 JPA심화 (3) (0) | 2022.12.14 |
| 2022.12.13 JPA 심화 (2) (0) | 2022.12.13 |
| 2022.12.12 입문 주차 복습, 영속성 (0) | 2022.12.12 |