TIL

TIL 221006 더 깊이 고민해보아야 할 문제들

Vince_rf 2022. 10. 6. 21:35

# DI를 쓰는 이유를 구체적으로!
A, B, C 클래스가 있다고 가정해보자.
new A(new B);
이런식으로 A 클래스에서 의존 객체를 B를 참조하여 직접 생성하는 방식을 사용하였을 때,

test1. class : new A(new B);
test2. class : new A(new B);
test3. class : new A(new B);

가 된다.

여기서 만약 A가 B가아닌 C를 참조해야하는 상황이 오면,

test1. class : new A(new C);
test2. class : new A(new C);
test3. class : new A(new C);

로 모두 고쳐주어야 하는 불상사가 발생한다.

여기서 DI는 의존 객체를 외부로부터 받아오기 때문에,

A는 B를 참고한다 라는 파일이 있다면

test1. class : getBean()
test2. class : getBean()
test3. class : getBean()

A는 C를 참조하기 위해서는 A는 B를 참고한다고 명시한 것에서 A는 C를 참고한다. 라고 바꾸기만 하면

test1. class : getBean()
test2. class : getBean()
test3. class : getBean()

이 코드를 여전히 사용할 수 있다.

# Fetch 타입 EAGER, LAZY에 대해서 깊은 이해 요구 - 굳이 LAZY를 쓴 이유가 무엇인가? 

EAGER는 LAZY와 다르게 엔티티 조회시에 바로 연관관계에 있는 모든 Entity를 가지고 온다.
EAGER는 복잡한 쿼리를 많이 풀어내기 위해서 사용하는 JPQL에서 N+1 문제를 일으킨다.
즉, 연관관계의 주인을 조회하는 쿼리에다가 @ManyToOne으로 묶여있는 N개 만큼 쿼리 N개를 보내는 현상이다.
데이터베이스에 저장된 값이 방대해질수록 아찔해지는 경우이다.
LAZY는 연관관계된 테이블을 프록시로 가지고 있으면서, 필요한 시점에 쿼리를 호출한다.
LAZY는 계속 쿼리를 여러번 날려서 조회를 해야할까? 라는 의문이 생기게 되는데, 이런 경우를 위해서 JPQL의 을 통해서 해당 시점에 한방 쿼리로 가져와서 쓸 수 있다.

TIL 220712 실전프로젝트 트러블슈팅 (tistory.com)
Lazy 사용시 같은 트랜잭션이 아닐시 프록시를 초기화 하지못해 발생하는 오류라고 한다.

해결방법으로는 1. LAZY를 EAGER로 바꿔주기 ( 위에 상술하듯이, 추천하는 방법은 아니라고 한다 ), 2. @Transactional을 사용해 같은 트랙잭션으로 묶어주기가 있다.

참고로 @OneToMany는 디폴트값이 LAZY였다..

 

# Redis 관련질문

Embedded Redis와 관련이 있었는데, 테스트를 위해 Redis 서버를 직접 설치하는것보다는 좀더 간편하게 Redis를 사용하기 위하여 Embedded Redis를 이용한다고 한다. Embedded Redis는 SpringBoot 실행시 내부적으로 같이 구동되며 종료시엔 Redis도 같이 종료되므로 테스트 환경에서 사용하기 적합하다고 한다.

# H2 데이터베이스를 휘발성 데이터베이스로 사용하지 않는 법 ( 어플리케이션 구동 시마다 데이터를 날리지 않는 법 )

- 답변 작성 예정

# AOP를 프로젝트에서 사용해보았는가?

- 답변 작성 예정

'TIL' 카테고리의 다른 글

TIL 221025  (0) 2022.10.26
221009 TIL...이 아닌 일기  (0) 2022.10.09
TIL 221004  (1) 2022.10.04
TIL 221003 개인프로젝트 queryDsl 트러블슈팅  (1) 2022.10.03
TIL 221001 개인프로젝트 SQL 쿼리  (0) 2022.10.01