Spring Boot Part4 - JPA 고급매핑, 프록시, SpringDataJPA
상속관계매핑
조인테이블 전략
- 상속받은 클래스들을 조인 테이블로 연관 관계를 만들어 관리한다.
@Entity
@Table(name = "item")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Item {
...
}
@Entity
public class Car extends Item {
...
}
싱글테이블 전략
- 상속받은 클래스들을 같은 테이블의 필드를 추가하여 관리한다.
@Entity
@Table(name = "item")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
...
}
@Entity
@DiscriminatorValue("CAR")
public class Car extends Item {
...
}
@MappedSuperclass
- 각각의 엔티티마다 공통적으로 사용되는 필드들을 superclass로 선언해서 상속받는다.
@MappedSuperclass
public class BaseEntity {
@Column(name = "created_at, columnDefinition = "TIMESTAMP")
private LocalDateTime createdAt;
}
@Entity
@Table(name = "orders")
public class Order extends BaseEntity {
...
}
식별자 클래스
- JPA에선 복합키를 사용하려면 별도의 식별자 클래스가 필요하다.
@IdClass
@Getter
@Setter
@Entity
@IdClass(TestId.class)
public class Test {
@Id
private String id1;
@Id
private String id2;
}
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class TestId implements Serializable {
private String id1;
private String id2;
}
@EmbeddedId
@Getter
@Setter
@Entity
public class Test {
@EmbeddedId
private TestId id;
}
@Getter
@Setter
@EuqualsAndHashcode
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class TestId implements Serializable {
private String id1;
private String id2;
}
프록시
객체 그래프 탐색
- Entity는 RDB와 매핑 되어 있다.
- 그래서 정보를 가지고 오려면 order.gerOrderItem().getItem()과 같이 탐색하는 걸 객체 그래프 탐색이라 한다.
- 하지만 프록시가 없다면 미리 연관된 객체들의 정보를 모두 가져와야 한다.
프록시 객체
- JPA는 프록시 객체를 사용하여 연관된 객체를 처음부터 DB에서 조회하지 않고 실제 사용하는 것 처럼 보이게 한다. ( 이것을 Transparent 이라 한다. 반대는 Virtual라 함. )
- 실제로 get을 해서 사용 할 때, 조회한다.
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
private List<Order> orders = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id")
private Member member;
- 처음 사용할 때, 한번만 초기화 된다. 하지만 영속성 컨텍스트의 도움을 받아야 한다. 준영속 상태의 프록시를 초기화하면 LazyInitializationException 예외가 발생한다.
- 프록시 객체를 통해서 실제 엔티티에 접근 할 수 있다.
영속성 전이 (CASCADE)
고아객체
- 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제하는 기능
@OneToMany(mappedBy = "member", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Order> orders = new ArrayList<>();
SpringDataJPA
JpaRepository
- 데이터 저장 계층에 대한 인터페이스를 지원한다.
- CRUD 작업을 편리하게 할 수 있다. ( 메서드로 가능함 )
import org.springframework.data.jpa.repository.JpaRepository;
public interface OrderRepository extends JpaRepository<Order, String> {
}