Application/JPA

    [JPA] 지연 로딩 N+1 문제와, JPQL 페치 조인

    JPA에 대해서 헷갈렸던 개념들을 위주로 정리하는 글입니다. 페치 조인 페치(fetch) 조인은 SQL 조인의 종류가 아니라 JPQL에서 성능 최적화를 위해 제공하는 기능. # JPQL SELECT m FROM Member m JOIN FETCH m.team # SQL SELECT m.*, t.* FROM Member m INNER JOIN Team t ON m.team_id = t.id 페치 조인을 알아보기 전에 페치 조인을 사용해야 하는 상황을 먼저 보자. 지연 로딩과 N + 1 문제 글로벌 로딩 전략이 지연 로딩으로 설정되어 있고, (Lazy) 회원 1 - 팀 A, 회원 2, 팀 B, 회원 3, 팀 B라는 데이터가 있다고 가정하자. String query = "select m From Member ..

    [JPA] 값 타입, 임베디드 타입, @Embeddable

    JPA의 데이터 타입을 크게 분류하면 엔티티 타입과 값 타입으로 나눌 수 있다. 엔티티 타입 @Entity로 정의하는 객체. 식별자(@Id)를 통해 지속해서 추적할 수 있음. 값 타입 int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체. 엔티티 타입과는 달리 식별자가 없어 추적할 수 없다. 임베디드 타입 (복합 값 타입) 새로운 값 타입을 직접 정의해서 사용하는 타입. @Entity // 엔티티 타입 public class Member { @Id @GeneratedValue private Long id; @Embedded private Period period; } @Embeddable // 값 타입 (임베디드 타입) public class Period { priva..

    [JPA] 영속성 전이 Cascade란?, 고아 객체 제거 OrphanRemoval란?

    JPA에 대해서 헷갈렸던 개념들을 위주로 정리하는 글입니다. 자바 ORM 표준 JPA 프로그래밍 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 JPA에서는 CASCADE 옵션으로 영속성 전이를 제공. 영속성 전이: 저장 CascasdeType.PERSIST @Entity public class Parent { ... @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) private List children = new ArrayList(); ... } private static void save(EntityManager em) { Child child1 = new Child(); Child child2 = n..

    [JPA] 프록시란? 지연로딩 vs 즉시 로딩란?

    JPA에 대해서 헷갈렸던 개념들을 위주로 정리하는 글입니다. 프록시란? 객체는 객체 그래프를 통해 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다. JPA 구현체들은 이 문제를 해결하기 위해 프록시라는 기술을 사용한다. 프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. 하지만 자주 함께 사용하는 객체들은 조인을 사용해서 함께 조회하는 것이 효과적이다. JPA는 즉시 로딩과 지연 로딩이라는 방법으로 둘을 모두 지원한다. (fetchJoin의 방법도 있음) 프록시 클래스는 실제 클래스를 상속 받아서 만들어져 실제 클래스와 겉 모양이 같음. 프록시 객체는 실제 ..

    [JPA] 영속성 컨텍스트란?

    JPA에 대해서 헷갈렸던 개념들을 위주로 정리하는 글입니다. JPA 내부 동작 원리를 알려면 영속성 컨텍스트를 알아야 함. EntityManagerFactory는 여러 스레드에서 동시에 접근해도 안전하지만, 생성하는 비용이 상당히 크다. 따라서 EntityManagerFactory에서 요청이 올 때마다 생성 비용이 거의 없는 EntityManager를 생성한다. (EntityManager는 Thread Safe하지 않아, 여러 스레드가 동시에 접근하면 동시성 문제가 발생한다 = 요청(스레드)별로 한 개 씩 할당) 이때 만들어진 EntityManager는 내부적으로 Database Connnection을 사용해서 DB를 사용한다. (참고로 EntityManager는 데이터베이스 연결이 꼭 필요한 시점까지 ..