아카이브

[스프링 데이터 JPA] JPA 프로그래밍 6: Fetch 본문

Spring/스프링 데이터 JPA

[스프링 데이터 JPA] JPA 프로그래밍 6: Fetch

주멘이 2021. 1. 10. 22:16

Fetch

연관 관계의 엔티티를 어떻게 가져올 것이냐... 지금 (Eager)? 나중에(Lazy)?

  • @OneToMany의 기본값은 Lazy : 자식 값들을 한 번에 다 가져오는 것은 불필요하고 사용될지도 모르니까 나중에 가져온다.
  • @ManyToOne의 기본값은 Eager : 부모값은 한 번에 바로 가져온다.

JpaRunner에서 테스트

package me.jumen.springdatajpa;

import org.hibernate.Session;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

/*
 * @Transactional - EntityManager 와 관련된 모든 행위들은 한 트랜잭션 안에서 일어나야 한다.
 * 1. 클래스에 붙이면 모든 메서드에 적용된다.
 * 2. 메서드에만 붙일 수도 있다.
 * */

@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;    // JPA 핵심 클래스 (SpringBoot의 ApplicationContext와 같은 위상)


    @Override
    public void run(ApplicationArguments args) throws Exception {

        //Post-Comment CASCADE 예제
        Post post = new Post();
        post.setTitle("Spring DATA JPA 포스트 타이틀");

        List<Comment> comments = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Comment comment = new Comment();
            comment.setComment("Comment " + i);
            post.addComment(comment);
        }

        Session session = entityManager.unwrap(Session.class);  /* 하이버네이트의 가장 핵심적인 API는 Session이다.*/
//        session.save(post);
        post = session.get(Post.class, 1l);
        System.out.println("==========Post는 Fetch.LAZY이기 때문에 comments까지 바로 가져오지 않는다.");
        System.out.println(post.getTitle());

        post.getComments().forEach(c -> {
            System.out.println(c.getComment());
        });

        Comment comment = session.get(Comment.class, 5l);
        System.out.println("========== Comment는 Fetch.EAGER이기 때문에 query는 한번만 날아가서 post까지 가져온다");
        System.out.println(comment.getComment());


    }
}

 

Hibernate에서 load() 와 get()의 차이점

www.tutorialspoint.com/difference-between-get-and-load-in-hibernate

 

Difference Between get() and load() in Hibernate

Difference Between get() and load() in Hibernate In hibernate, get() and load() are two methods which is used to fetch data for the given identifier. They both belong to Hibernate session class. Get() method return null, If no row is available in the sessi

www.tutorialspoint.com

  • load: 가져오려 할때 없으면 예외를 던짐 Proxy로도 가져올 수 있음
  • get: 무조건 DB에서 가져옴 해당하는 게 없으면 예외를 던지지 않고 무조건 레퍼런스를 null로 만듦