프록시(Proxy)란 무엇인가?
프록시는 하이버네이트가 만든 가짜 클래스입니다. 실제 엔티티 클래스의 형태를 그대로 가지고 있으며, 이론상으로는 실제 클래스와 구분하지 않고 사용할 수 있습니다.
프록시의 특징
- 형태 동일성: 실제 클래스를 상속 받아서 만들어졌기 때문에 형태가 실제 클래스와 똑같습니다.
- 사용의 투명성: 이론상 실제 클래스와 구분하지 않고 사용할 수 있습니다.
프록시의 동작 매커니즘
Member member = em.getReference(Member.class, "id1");
위 코드가 실행되면, 프록시에 의해 가짜 객체가 만들어집니다. 만약 member.getName() 메서드를 호출하면, 프록시 객체는 영속성 컨텍스트에게 초기화를 요청합니다. 그 후, 데이터베이스 조회를 통해 받은 값을 실제 엔티티를 생성하여 반환합니다.
프록시의 특징
- 한 번만 초기화: 프록시는 반드시 한 번만 초기화됩니다.
- 초기화 후 접근: 프록시 객체를 초기화할 때 실제 엔티티로 바뀌는 것이 아니라, 초기화된 프록시 객체를 통해 엔티티에 접근할 수 있습니다.
따라서, 비교할 때는 반드시 instanceof를 사용해야 합니다. JPA에서는 동일성 비교(==)가 가능하므로 프록시와 실제 객체의 순서는 상관없습니다.
즉시 로딩(Eager Loading) vs 지연 로딩(Lazy Loading)
지연 로딩
@ManyToOne(fetch = FetchType.LAZY) private Team team;
- 특징: 지연 로딩을 사용하면 Member 객체가 생성될 때 team 정보는 데이터베이스에서 가져오지 않습니다. team 정보가 필요한 순간에 데이터베이스 쿼리를 실행하여 가져옵니다.
- 장점: 필요할 때만 데이터를 가져오므로 성능에 유리합니다.
즉시 로딩
@ManyToOne(fetch = FetchType.EAGER) private Team team;
- 특징: 즉시 로딩을 사용하면 Member 객체가 생성될 때 team 정보를 즉시 데이터베이스에서 가져옵니다.
- 단점: 모든 데이터를 미리 가져오기 때문에 필요 없는 데이터를 불필요하게 조회할 수 있습니다.
실무 권장 사항
- 즉시 로딩 사용 금지: 실무에서는 즉시 로딩을 사용하지 말고 반드시 지연 로딩만 사용해야 합니다.
- 이유: N+1 문제 발생 가능성 때문입니다. 예를 들어, select m from Member m 쿼리가 실행되면, 기본 쿼리 1개와 각 멤버의 팀 정보를 가져오는 추가 쿼리가 실행되어 총 11개의 쿼리가 나갈 수 있습니다. 원하는 것은 10개의 배열이지만, 실제로는 11개의 쿼리가 실행됩니다.
Cascade란 무엇인가?
- 영속화 전이(Cascade): 부모와 자식 엔티티가 있을 때, 부모 엔티티만 영속화하면 자식 엔티티도 자동으로 영속화되는 기능입니다.
- 고아 객체(Orphan): 부모 엔티티와의 연관관계가 끊어진 자식 엔티티를 자동으로 삭제합니다.
이러한 기능들은 엔티티 간의 관계를 관리하고, 데이터베이스와의 상호작용을 최적화하는 데 중요한 역할을 합니다.
'JAVA > JPA' 카테고리의 다른 글
인프런 JPA 서비스 최적화 방법 "김영한" -PlusUltraCode- (0) | 2024.07.25 |
---|---|
인프런 JPA 9화 값 타입 "김영한 강사" -PlusUltraCode- (1) | 2024.07.24 |
인프런 JPA 10화 객체지향 쿼리 언어1 - 기본 문법 "김영한 강사" -PlusUltraCode- (1) | 2024.07.20 |
인프런 JPA 7화 고급 매핑 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |
인프런 JPA 6화 다양한 연관관계 매핑 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |