728x90

분류 전체보기 331

지연 로딩(Lazy Loading) - feat. 프록시

지연 로딩을 사용하려면 @ManyToOne의 fetch 속성을 FetchType.Lazy로 지정한다. @Entity public class Member { //지연 로딩 설정 //... @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TEAM_ID") private Team team; //... } Member member = em.find(Member.class, "member1"); //지연 로딩 실행 코드 Team team = member.getTeam(); //객체 그래프 탐색 team.getName(); //팀 객체 실제 사용 em.find(Member.class, "member1")를 호출하면 회원만 조회하고 팀은 조회하지 않는다. 대신에 같이..

JPA 2022.06.14

임베디드 타입(@Embeddable, @Embedded)

임베디드 타입 새로운 값 타입을 직접 정의할 수 있음 JPA는 임베디드 타입이라고 함. 주로 기본 값 타입을 모아서 복합값 타입이라고도 함. int, String과 같은 값 타입 재사용이 가능하며 높은 응집도 Period.isWork()처럼 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있음 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 Entity에 생명주기를 의존함 Member @Entity public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String username; // 기간 @Embedded // Period..

JPA 2022.06.13

@MappedSuperclass

부모 클래스는 테이블과 매핑하지 않고 부모클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶으면 @MappedSuperclass를 사용한다. 회원(member)과 판매자(seller)는 서로 관계가 없는 테이블과 엔티티이다. 테이블을 그대로 두고 객체 모델의 id, name 두 공통 속성을 부모 클래스로 모으로 객체 상속 관계로 만들어보자. @MappedSuperclass public abstract class BaseEntity { @Id @GeneratedValue private Long Id; private String name; ... } @Entity public class Member extends BaseEntity { //ID 상속 //NAME 상속 private String em..

JPA 2022.06.13

다대일 양방향 [N:1, 1:N] 관계

Member가 연관관계 주인이고(외래키 있는 다쪽인 곳), Team은 연관관계 주인이 아닐 때, 다음 코드를 통해 다대일 양방향 관계를 알아보자 @Entity public class Member { //member 엔티티 @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; private String username; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; public void setTeam(Team team) { this.team = team; //무한 루프에 빠지지 않도록 체크 if(!team.getMembers().contains(this)){ team.getMember..

JPA 2022.06.13

연관관계 편의 메소드 작성 시 주의사항(part.2)

사실 setTeam() 메소드에는 버그가 있다. member1.setTeam(teamA); //1 member2.setTeam(teamB); //2 Member findMEmber = teamA.getMember(); //member1이 여전히 조회된다. teamB로 변경할 때 teamA -> member1 관계를 제거하지 않았다. 연관관계를 변경할 때는 기존 팀이 있으면 기존 팀과 회원의 연관관계를 삭제하는 코드를 추가해야 한다. 따라서 다음 코드처럼 기존 관계를 제거하도록 코드를 수정해야 한다. public void setTeam(Team team) { //기존 팀과 관계를 제거 if (this.team != null) { this.team.getMembers().remove(this); //this..

JPA 2022.06.12

연관관계 편의 메소드(part.1)

양방향 연관관계는 결국 양쪽 다 신경 써야 한다. 다음처럼 member.setTeam(team) 과 team.getMembers().add(member)를 각각 호출하다 보면 실수로 둘 중 하나만 호출해서 양항향이 깨질 수 있다. member.setTeam(team); team.getMembers().add(member); 양방향 관계에서 두 코드는 하나인 것 처럼 사용하는 것이 안전하다. Member 클래스의 setTeam() 메소드를 수정해서 코드를 리팩토링해보자. public class Member { private Team team; public void setTeam(Team team){ this.team = team; team.getMembers().add(this);//this 는 membe..

JPA 2022.06.12

고아 객체(feat. orphanRemoval)

JPA는 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능을 제공하는데 이것을 고아 객체(ORPHAN) 제거라 한다. 이 기능을 사용해서 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티가 자동으로 삭제된다. @Entity public class Parent { @Id @GeneratedValue private Long id; @OneToMany(mappedBy = "parent", orphanRemoval = true) private List children = new ArrayList(); ... } 위 코드와 같이 orphanRemoval = true로 설정하면, 컬렉션에서 제거한 엔티티는 자동으로 삭제된다. Parent parent1 = em.find(Pare..

JPA 2022.06.12

영속성 전이에 관해(부제 : CASCADE)

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이(transitive persistence) 기능을 사용하면 된다. JPA는 CASCADE 옵션으로 영속성 전이를 제공한다. @Entity public class Parent {//부모 엔티티 @Id @GeneratedValue private Long id; @OneToMany(mappedBy = "parent") private List children = new ArrayList(); ... } @Entity public class Child {// 자식 엔티티 @Id @GeneratedValue private Long id; @ManyToOne private Parent parent; ... } JPA에서 ..

JPA 2022.06.11

상속관계 매핑 전략(@DiscriminatorColumn 란?)

통합 테이블로 변환하는 단일 테이블 전략(SINGLE_TABLE) 서비스 규모가 크지 않고, 굳이 조인 전략을 선택해서 복잡하게 갈 필요가 없다고 판단 될 때에는 한 테이블에 다 저장하고, DTYPE으로 구분하는 단일 테이블 전략을 선택할 수 있다. INSERT 쿼리도 한 번, SELECT 쿼리도 한 번이다. 조인할 필요가 없고, 성능이 좋다. 단일 테이블 적용 아래와 같이, strategy를 SINGLE_TABLE로 변경하면 끝난다. JPA의 장점이다. 테이블 구조의 변동이 일어났는데, 코드를 거의 손대지 않고 어노테이션만 수정했다. 만약 JPA를 쓰지 않았더라면, 테이블 구조의 변경이 일어나면 거의 모든 코드를 손대야 할 것이다. 단일 테이블 전략에서는 @DiscriminatorColumn을 선언해 ..

JPA 2022.06.05

[스프링 부트와 AWS로 혼자 구현하는 웹 서비스] p.62 실행 오류 해결법

오류 로그 package com.jojoldu.book.awsspring.springboot.web; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.Mo..

Spring 2022.05.16
728x90