본문 바로가기

전체 글29

[JPA] 일대다 조인할때 영속성 컨텍스트 내부 모습 & distinct 엔티티와 데이터베이스를 매핑을 아래와 같이 한다. @Entity class User{ ... @ManyToOne(fetch = FetchType.LAZY ) private Team team; ... } @Entity class Team{ @OneToMany(mappedBy = "team") // 기본적으로 LAZY private List users = new ArrayList(); ... } 데이터 베이스는 미리 데이터를 인서트 해놓았다. 팀을 기준으로 유저들을 join 하면 재밌는 일이 발생한다. 즉 아래와 같은 코드가 있을때 출력을 생각해보자. List teams = em.createQuery("select t from Team t join fetch t.users").getResultList(); .. 2020. 8. 6.
[JPA / JPQL] 페치조인 & 지연로딩 지연로딩을 기본 페치전략으로 가져가는 경우 어떤 문제점이 있을까?? 예시로 바로 살펴보자. @Entity class User{ ... @ManyToOne(fetch = FetchType.LAZY ) private Team team; ... } @Entity class Team{ @OneToMany(mappedBy = "team") // 기본적으로 LAZY private List users = new ArrayList(); ... } 영속성 컨텍스트는 깨끗하게 비워져있는 상태라고 가정한다. 아래의 데이터베이스 상황에서 쿼리를 날린다면?? List users = em.createQuery("select u from User u",User.class).getResultList(); for (User u : u.. 2020. 8. 6.
[JPA / JPQL] @ManyToOne, @OneToOne 과 묵시적 조인 JPQL 은 엔티티를 대상으로 날리는 sql 과 비슷하다. JPQL에서 주의해야할 점이 있다. 만약 User 라는 객체에 Team이라는 객체가 @ManyToOne으로 매핑되었다고 가정하자. 유저마다 유저가 속한 팀을 가져오라는 쿼리는 다음과 같다. select u.team from User u ; 그러면 당연하게 받아 들일 수도 있다. 하지만 실제 sql 을 보면 JOIN문이 들어가 있다. 그럴수 밖에 없다. 유저의 팀을 가져오려면 유저와 팀을 조인해야한다. 이를 JPQL에서는 묵시적으로 조인해준다. 실제 날리는 쿼리는 아래와 같다. select t from User u join u.team t 이처럼 단일값을 연관관계로 가지는@ManyToOne 이나 @OneToOne 에서 "." 을 이용하여 가져온다면.. 2020. 8. 6.
[JPA] @Embeddable , @Embedded class User{ private int age; private int money; private String name; private String 초등학교; private String 중학교; private String 대학교; ... } User 가 가지고있는 속성이 너무 지저분하고 한눈에 알아보기 힘들다. 이때 초등학교,중학교,대학교 는 학교라는 공통적인 속성안에 포함되어 있는 것이므로 학교라는 클래스를 따로 만들어서 관리하면 되지 않을까? class User{ private int age; private int money; private String name; private 학교 학교정보; ... } 좀더 심플해졌다. 하지만 문제가 있는데 학교정보라는 값이 공유가능한지가 문제이다. 왜냐하면 기존.. 2020. 8. 6.
[JPA] CASCASDE 옵션 & orphanRemoval CASCADE의 옵션으로 ALL PERSIST REMOVE .... 등이 있는데 ALL에 대해서만 설명하겠다. CACADE는 엔티티가 영속화될때, 해당되는 엔티티도 영속화 할 것인지 옵션으로 정할 수있게한다. @OneToMany 와 @ManyToOne 둘다 cascade 옵션을 가지고 있다. 영속화에 대해서 편리함을 제공한다. 하지만 영속화를 전이할때, 전이대상이 되는 객체가 null 이거나 등 예상치 못한 부작용이 있을 수있다. 그래서 나름의 기준을 정하는 것이 좋다. 1. 단일 소유여야 한다. 나만 소유하면 되지 다른 객체들도 소유하고 있으면 곤란하다. 2. 생명주기가 같아야 한다. 내가 사라지면 내가 가진 소유물도 사라져야한다. 하지만 사라지지 않아도 되는데 cascade를 쓰면 문제가 있다. (고.. 2020. 8. 6.
[JPA] 프록시 (Proxy) 객체 & fetch = EAGER & LAZY class Order{ @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="user_id") private User user; .... } 여기서 @ManyToOne은 알겠는데 fetch 에서 LAZY는 무엇인가?? EAGER 는 무엇인가?? 왜 이런 설정이 있는가?? 보통 프록시라고 하면 프록시서버에 관한 내용이 많이 나온다. 단어만 가지고 생각하면 프록시는 "가짜" 와 관련된 느낌의 단어다. 그렇다. 프록시 객체는 가짜객체다. 프록시 객체는 실제 클래스의 객체를 상속 받은 객체이다. 그리고 실제 객체에 대한 Target 즉 참조를 가지고 있다. 초기의 프록시 객체는 이러한 참조만 가지고 있고 실제 내용은 텅텅비어있다. 이런 프록시 객체는 왜 만드는 것인가? .. 2020. 8. 6.
[JPA] @Inheritance , @DiscriminatorValue, @DiscriminatorColumn 전략 설명에 앞서 테이블을 정의해 보자. 상속관계의 매핑을 위한 3가지 방법이 있다. 1.JOINED 2.SINGLE_TABLE 3.TABLE_PER_CLASS 1. JOINED @Inheritance(strategy = InheritanceType.JOINED) 이는 가장 정규화된 테이블로 관리를 해준다. 조회할때 항상 조인해서 가져오기 때문에 성능이 떨어지지만, 그외 저장효율이나 유지보수가 용이하다. @DIscriminatorColumn이 디폴트가 아니지만 설정해 주는 것이 좋다. 2. SINGLE_TABLE 이는 하나의 테이블에 모든 속성을 다 집어넣는다. 조회에서 좋은 성능을 보인다. 단순한 상속관계에서 주로 많이 쓴다. 또한 DiscriminatorColumn 이 기본으로 깔려서 들어간다. 3.TAB.. 2020. 8. 6.
[JPA] @MappedSuperClass 란? 엔티티를 살펴보면 상당히 공통적인 필드들이 많다. 언제 생성되었는지 언제 수정되었는지 등등 ... 이러한 필드들을 공통적으로 관리할 수 없을까 ?? 해서 나온것이 @MappedSuperClass다. @MappedSuperClass 는 단순히 매핑정보만 제공할 뿐이며 그이상 그이하도 아니다. 따라서 abstract로 추상클래스로 선언하는 경우가 많다. 보통의 엔티티에서는 @MappedSuperClass를 상속받아서 쓰면된다. 그렇다고 상속관계의 매핑이 전혀 아니다. 헷갈리면 안된다. 예) @MappedSuperClass abstract class 시간찍기{ 업데이트시간, 생성시간, } class 객체 extends 시간찍기{ 이름; 나이; ..... } 위처럼 생성했을 때, 데이터베이스에서 보면 객체에는 .. 2020. 8. 6.
[JPA] @ManyToOne , @OneToMany, @JoinColumn 데이터 베이스공부를 하다보면 조인이라는 개념을 배운다. 우리가 아는 가장 기본적인 조인은 두개의 테이블의 공통적인 요소를 끌고 오는 것이다. 예를 들어 과일상자테이블과 과일들의 테이블이 있다고 하자. 과일상자 기본키 과일상자 이름 1 상자1 2 상자2 과일의 기본키 과일상자의 기본키(왜래키) 과일 이름 3 1 사과 4 1 포도 5 1 배 6 2 오렌지 7 2 바나나 과일상자와 과일의 관계는 OneToMany이다. 두개의 테이블을 조인하면 어떻게 될까? 과일상자를 왼쪽으로 두고 left join을 했다고 가정하자. 과일상자 기본키 과일상자 이름 과일의 기본키 과일 이름 1 상자1 3 사과 1 상자1 4 포도 1 상자1 5 배 2 상자2 6 오렌지 2 상자2 7 바나나 이렇게 해서 "상자1" 과 "상자2" .. 2020. 8. 6.