JPA 26

영속성 전이: CASCADE

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이 기능을 사용하면 된다. 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 2023.07.31

즉시 로딩과 지연 로딩

즉시 로딩 즉시 로딩(Eager Loading)을 사용하려면 @ManyToOne의 fetch 속성을 FetchType.EAGER로 지정한다. // 즉시 로딩 설정 @Entity public class Member { ... @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "TEAM_ID") private Team team; ... } 위의 코드에서 회원과 팀을 즉시 로딩으로 설정했다. // 즉시 로딩 실행 코드 Member member = em.find(Member.class, "member1"); Team team = member.getTeam(); //객체 그래프 탐색 따라서 em.find(Member.class, "member1")로 회원을 조회하는..

JPA 2023.07.31

프록시

객체는 객체 그래프로 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다. JPA 구현체들은 이 문제를 해결하려고 프록시라는 기술을 사용한다. 프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. 하지만 자주 함께 사용하는 객체들은 조인을 사용해서 함께 조회하는것이 효과적이다. JPA는 즉시 로딩과 지연 로딩이라는 방법으로 둘을 모두 지원한다. 프록시 엔티티를 조회할 때 연관된 엔티티들이 항상 사용되는 것은 아니다. 예를 들어 회원 엔티티를 조회할 때 연관된 팀 엔티티는 비즈니스 로직에 따라 사용될 때도 있지만 그렇지 않을 때도 있다. //회원 엔티티 @Entit..

JPA 2023.07.28

@SecondaryTable : 엔티티 하나에 여러 테이블 매핑

@SecondaryTable을 사용하면 한 엔티티에 여러 테이블을 매핑할 수 있다. @Entity @Table(name = "BOARD") @SecondaryTable(name = "BOARD_DETAIL", pkJoinColumns = @PrimaryKeyJoinColumn(name = "BOARD_DETAIL_ID")) public class Board { @Id @GeneratedValue @Column(name = "BOARD_ID") private Long id; private String title; @Column(table = "BOARD_DETAIL") private String content; ... } Board 엔티티는 @Table을 사용해서 BOARD 테이블과 매핑했다. 그리고 @S..

JPA 2023.06.13

조인 테이블

데이터베이스 테이블의 연관관계를 설계하는 방법은 크게 2가지다. 1. 조인 컬럼 사용(외래 키) 2. 조인 테이블 사용(테이블 사용) ▼ 조인 컬럼 사용 테이블 간에 관계는 주로 조인 컬럼이라 부르는 외래 키 컬럼을 사용해서 관리한다. 외래키에 null을 허용하는 관계를 선택적 비식별관계라한다. 회원과 사물함을 조인할 때 외부조인(OUTER JOIN)을 사용해야한다. 실수로 내부 조인을 사용하면 사물함과 관계가 없는 회원은 조회되지 않는다. 그리고 회원과 사물함이 아주 가끔 관계를 맺는다면 외래 키 값 대부분이 null로 저장되는 단점이 있다. ▼ 조인 테이블 사용 조인 테이블이라는 별도의 테이블을 사용해서 연관관계를 관리한다. 조인 컬럼을 사용하는 방법은 단순히 외래키 컬럼만 추가해서 연관관계를 맺지만..

JPA 2023.06.13

복합 키와 식별 관계 매핑

식별 관계 vs 비식별관계 식별관계 : 부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계 비식별관계 : 부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계 비식별관계는 외래 키에 NULL을 허용하는지에 따라 필수적 비식별 관계와 선택적 비식별 관계로 나눈다. 필수적 비식별 관계(Mandatory): 외래 키에 NULL을 허용하지 않는다. 연관관계를 필수적으로 맺어야 한다. 선택적 비식별 관계(Optional): 외래 키에 NULL을 허용한다. 연관관계를 맺을지 말지 선택할 수 있다. 복합 키: 비식별 관계 매핑 기본 키를 구성하는 컬럼이 하나면 다음처럼 단순하게 매핑한다. @Entity public class Hello() { @Id privat..

JPA 2023.06.08

@MappedSuperclass

지금까지 학습한 상속 관계 매핑은 부모 클래스와 자식 클래스를 모두 데이터베이스 테이블과 매핑했다. 부모 클래스는 테이블과 매핑하지 않고 부모 클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶으면 @MappedSuperclass를 사용하면 된다. @MappedSuperclass는 비유를 하자면 추상 클래스와 비슷한데 @Entity는 실제 테이블과 매핑되지만 @MappedSuperclass는 실제 테이블과는 매핑되지 않는다. 이것은 단순히 매핑 정보를 상속할 목적으로만 사용된다. 회원(Member)와 판매자(Seller)는 서로 관계가 없는 테이블과 엔티티다. 테이블은 그대로 두고 객체 모델의 id, name 두 공통 속성을 부모 클래스로 모으고 객체 상속 관계로 만들어보자. @MappedSup..

JPA 2023.05.11

상속 관계 매핑

관계형 데이터베이스에는 객체지향 언어에서 다루는 상속이라는 개념이 없다. 대신에 슈퍼타입(Super-type)과 서브타입(Sub-type) 관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다. ORM에서 말하는 상속 관계 매핑은 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계를 매핑하는 것이다. 여기서 저 중간에 엑스표는 Exclusive(상호배제관계)를 의미하고, 하나의 슈퍼타입 엔티티가 여러개의 서브타입 엔티티를 가질 수 없다는 것을 의미한다. 반대로 엑스표가 없으면 Inclusive(상호보완관계)를 의미하고, 하나의 슈퍼타입 엔티티가 여러개의 서브타입 엔티티를 가질 수 있다는 것을 의미한다. 슈퍼타입, 서브타입 논리모델을 실제 물리모델인 테이블로 구현할 때는 3가지 방법을 선택할 수 ..

JPA 2023.05.11

다양한 연관관계 매핑 (2)

일대일 [1:1] 일대일 관계는 양쪽이 서로 하나의 관계만 가진다. 예를 들어 회원은 하나의 사물함만 사용하고 사물함도 하나의 회원에 의해서만 사용된다. ​ 일대일 관계는 다음과 같은 특징이 있다. 일대일 관계는 그 반대도 일대일 관계이다. 테이블 관계에서 일대다, 대대일은 항상 다(N)쪽이 외래 키를 가진다. 반면에 일대일 관계는 주 테이블이나 대상 테이블 둘 중 어느 곳이나 외래 키를 가질 수 있다. 테이블은 주 테이블이든 대상 테이블이든 외래 키 하나만 있으면 양쪽으로 조회할 수 있다. 따라서 일대일 관계는 주 테이블이나 대상 테이블 중에 누가 외래 키를 가질지 선택해야 한다. ​ ▼ 주 테이블에 외래 키 주 테이블에 외래 키를 두고 대상 테이블을 참조한다. 외래 키를 객체 참조와 비슷하게 사용할 ..

JPA 2023.04.27

다양한 연관관계 매핑 (1)

다대일 다대일 관계의 반대 방향은 항상 일대다 관계고 일대다 관계의 반대방향은 항상 다대일 관계다. 데이터베이스 관계에서 외래키는 항상 다 쪽에 있고, 다쪽이 연관관계의 주인이다. ​ 1. 다대일 단방향 [N:1] @Entity public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; private String username; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; ///Getter, Setter... } @Entity public class Team { @Id @GenerateValue @Column(name = "TEAM_ID") pr..

JPA 2023.04.27