[Spring JPA #6] Fetch

JPA Fetch

  • 연관된 엔티티의 정보를 언제 가져올 것인가를 정하는 것이다.
  • @OneToMany의 기본값은 Lazy
  • @ManyToOne의 기본값은 Eager

@OneToMany 예제

package com.kyhslam;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Post {

    @Id @GeneratedValue
    private Long bno;

    private String title;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private Set<Reply> replys = new HashSet<>();

    public void addReply(Reply reply) {
        this.getReplys().add(reply);
        reply.setPost(this);
    }

    public Long getBno() {
        return bno;
    }

    public void setBno(Long bno) {
        this.bno = bno;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Set<Reply> getReplys() {
        return replys;
    }

    public void setReplys(Set<Reply> replys) {
        this.replys = replys;
    }
}
package com.kyhslam;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
public class Reply {

    @Id @GeneratedValue
    private Long id;

    private String content;

    @ManyToOne
    private Post post;

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }

    public Long getId() {
        return id;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
package com.kyhslam;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

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


@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;

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

//        Post post = new Post(); 
//        post.setTitle("Spring data Jpa");
//  
//        Reply reply = new Reply();
//        reply.setContent("Seeing jpa");
//        post.addReply(reply);
//          
//        Reply reply3 = new Reply(); 
//        reply3.setContent("Seeing jpa22");
//        post.addReply(reply3);


        Session session = entityManager.unwrap(Session.class);
        Post post =    session.get(Post.class, 1L);
        System.out.println("===============");
        System.out.println(post.getTitle());

//        session.save(post);
    }
}
  • 위와 같이 데이터를 가져올 경우, 연관관계에 있는 Reply 엔티티의 정보는 가져오지 않고 Post 엔티티에 대한 정보만 가져온다.

  • 그 이유는, @OneToMany 에서는 FetchType.LAZYDefault로 설정되어 있기 때문이다.

결과

Hibernate: 
    select
        post0_.bno as bno1_0_0_,
        post0_.title as title2_0_0_ 
    from
        post post0_ 
    where
        post0_.bno=?

만약 fetch = FetchType.EAGER 를 적용할 경우

@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Reply> replys = new HashSet<>();

아래와 같이 POST에 연관된 Reply정보를 가져온다.

Hibernate: 
    select
        post0_.bno as bno1_0_0_,
        post0_.title as title2_0_0_,
        replys1_.post_bno as post_bno3_1_1_,
        replys1_.id as id1_1_1_,
        replys1_.id as id1_1_2_,
        replys1_.content as content2_1_2_,
        replys1_.post_bno as post_bno3_1_2_ 
    from
        post post0_ 
    left outer join
        reply replys1_ 
            on post0_.bno=replys1_.post_bno 
    where
        post0_.bno=?

@ManyToOne 예제

package com.kyhslam;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

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


@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

    @PersistenceContext
    EntityManager entityManager;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Reply reply = session.get(Reply.class, 2l);
        System.out.println("===========");
        System.out.println(reply.getContent());
        System.out.println(reply.getPost().getTitle());
    }
}
  • Reply 엔티티를 가져올 경우 자동적으로 매핑되어 있는 Post 엔티티에 대한 정보를 가져오게 된다.

  • 그 이유는 @ManyToOne 어노테이션은 FetchType.EagerDefault설정으로 되어 있어 연관된 엔티티의 정보를 모두 가져온다.

Hibernate: 
    select
        reply0_.id as id1_1_0_,
        reply0_.content as content2_1_0_,
        reply0_.post_bno as post_bno3_1_0_,
        post1_.bno as bno1_0_1_,
        post1_.title as title2_0_1_ 
    from
        reply reply0_ 
    left outer join
        post post1_ 
            on reply0_.post_bno=post1_.bno 
    where
        reply0_.id=?
===========
Seeing jpa
Spring data Jpa

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

[Spring JPA #11] 쿼리 실습  (0) 2020.07.19
[Spring JPA #7] Query  (0) 2020.07.15
[Spring JPA #5] 엔티티 상태와 Cascade  (0) 2020.07.14
[Spring JPA #4] 관계 맵핑  (0) 2020.06.28
[Spring JPA #3] Entity 매핑 및 Value 타입  (0) 2020.06.27

댓글

Designed by JB FACTORY