시냅스

JPA 즉시 로딩과 지연 로딩, 영속성 전이와 고아 객체 본문

Java, Spring/JPA

JPA 즉시 로딩과 지연 로딩, 영속성 전이와 고아 객체

ted k 2022. 9. 17. 14:23

즉시 로딩과 지연 로딩

  • 즉시로딩은 엔티티를 로딩하면서 관련된 모든 엔티티를 함께 로딩 하는것
  • 지연로딩은 필요한 시점에 가져오는 것을 말한다.
  • 가급적 지연 로딩만 사용해야 한다.
  • 즉시 로딩을 적용하면 JPQL에서 N + 1 문제를 일으킨다.
    • 만약 Member가 외래키를 갖고 있는 주인이고, Member가 3개에 각 Member의 소속된 팀이 전부 다르다면
    • 쿼리는 4번이 실행된다 (member, team1, team2, team3)
    • 이런 문제는 N(team) + 1(member)이라고 한다.
  • @ManyToOne, @OneToOne은 기본이 즉시 로딩으로 반드시 LAZY로 설정해야 한다.

 

영속성 전이 : CASCADE

  • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들 수 이싿.
  • 종류
    • ALL : 모두 적용
    • PERSIST : 영속
    • REMOVE : 삭제
    • MERGE : 병함
    • REFRESH
    • DETACH

 

고아 객체

  • 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제
  • orphanRemoval = true
  • 참조하는 곳이 하나일 때 사용해야 한다. - 게시판 첨부파일 등
  • 특정 엔티티가 개인 소유할 때 사용

 

영속성 전이 + 고아 객체

  • CascadeType.ALL + orphanRemoval = true
  • 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove() 로 제거
  • 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있음

 

@Entity
public class Parent {
    @Id @GeneratedValue
    private Long id;
    private String name;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) 
		// parent persist 될 때 child들도 다 persist됨
    private List<Child> childList = new ArrayList<>();

    public void addChild(Child child) {
        childList.add(child);
        child.setParent(this);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

parent

 

@Entity
public class Child {
    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;
    private String name;

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

child

 

Parent parent = new Parent();
Child child1 = new Child();
Child child2 = new Child();

parent.addChild(child1);
parent.addChild(child2);

em.persist(parent); // 자식들도 전부 저장 됨

em.flush();
em.clear();

Parent findParent = em.find(Parent.class, parent.getId());
em.remove(findParent); // 자식들도 전부 삭제 됨

 

'Java, Spring > JPA' 카테고리의 다른 글

JPA JPQL 경로 표현식과 패치 조인  (0) 2022.09.17
JPA 값 타입 관련 정리  (0) 2022.09.17
JPA 프록시 관련 정리  (0) 2022.09.17
JPA MappedSuperclass 정리  (0) 2022.09.17
JPA 상속관계 매핑 정리  (0) 2022.09.17
Comments