| ⚡ 지연로딩 실무에서 모든 연관관계는 지연로딩을 사용해라. 실무에서 즉시 로딩을 사용하지 마라. JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라 @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Item { @Id @GeneratedValue private Long id; private String name; private int price; } @Entity public class Member extends BaseEntity { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME..
⚡ 프록시 객체는 객체그래프로 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다. JPA는 이러한 문제를 해결하려고 프록시라는 기술을 사용한다. 프록시는 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. 하지만 자주 함께 사용하는 객체들은 조인을 사용해서 함께 조회하는 것이 효과적이다. JPA는 즉시로딩과 지연 로딩이라는 방법으로 둘을 지원한다. JPA는 연관된 객체를 함께 저장하거나 함께 삭제할 수 있는 영속성 전이와 고아 객체 제거라는 편리한 기능을 제공한다. ⚡ 프록시의 특징 프록시 객체는 처음 사용할 때 한 번만 초기화 된다. 프록시 객체를 초기화 할 때, 프록시 객체..
| 다대일 단반향 package hellojpa; import javax.persistence.*; @Entity public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String username; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public..
목표: 상속 관계 매핑과 @MappedSuperclass 알아보기 💡 상속 관계 매핑 관계형 데잍터베이스에는 객체지향 언어에서 다루는 상속이라는 개념이 없다. 대신 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다. 슈퍼타입 서브타입 논리 모델을 실제 물리 모델인 테이블로 구현할 때는 3가지 방법을 선택할 수 있다. 조인전략 : 각각을 모두 테이블로 만들고 조회할 때 조인을 사용한다 단일 테이블 전략 : 테이블을 하나만 사용해서 통합한다 구현 클래스마다 테이블 전략 : 서브 타입마다 하나의 테이블을 만든다. 1.조인전략 엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의기본 키를 받아서 기본키+외래키 로 사용하는 전략이다. 객체는 타입으로 구분할 수 있지만 테이블은 ..
📝 준영속 영속성 컨텍스트가 관리하는 영속 상태의 엔티티가 컨텍스트에서 분리된 것을 준영속 상태라 한다. 준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다. 준영속 상태로 만드는 방법 em.detach(entity): 특정 엔티티만 준영속 상태로 전환 em.clear(): 영속성 컨텍스트를 완전히 초기화 em.close(): 영속성 컨텍스트 종료 특징 거의 비영속 상태에 가깝다 식별자 값을 가지고 있다 이미 한번 영속 상태였으므로 식별자 값을 가지고 있다 지연로딩을 할 수 없다 지연로딩(Lazy Loading)은 실제 객체 대신 프록시 객체를 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트에서 데이터를 불러오는 방법이다.
📝 플러시 플러시(flush())는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다. 플러시라는 이름으로 인해 영속성 컨텍스트에 보관된 엔티티를 지운다고 생각하면 안 된다. 즉, 변경내용을 데이터베이스에 동기화하는 것이 플러시이다. 1. 동작방법 변경감지가 동작해서 영속성 컨텍스트에 잇는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾는다. 수정된 엔티티는 수정쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다. 쓰기지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다 2. 영속성 컨텍스트를 플러시하는 3가지 방법 em.flush() 호출 트랜잭션 커밋 시 flush() 자동호출 JPQL 쿼리 실행 시 flush() 자동호출 em.persist(memberA) em.persist(memberB) /..
📝 엔티티 매니저 팩토리와 엔티티 매니저 JPA가 제공하는 기능은 엔티티와 테이블을 매핑하는 설계부분과 매핑한 엔티티를 실제 사용하는 부분으로 나눌 수 있다. 엔티티 매니저는 엔티티를 저장하고 수정하고 삭제하고 조회하는 등 엔티티와 관련된 모든 일을 처리한다. 즉, 엔티티를 관리하는 관리자다. 엔티티 매니저 팩토리는 한개 만 만들어서 애플리케이션 전체에서 공유하도록 설계되어 있다. 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대 공유하면 안된다. 엔티티 매니저 트랜잭션을 시작할 때 커넥션을 획득한다. 📝 영속성 컨텍스트란? 영속성 컨텍스트(Persistence context)는 엔티티를 영구 저장하..
양방향 연관관계에서는 둘중 하나를 @JsonIgnore 해줘야 한다. 그렇지 않으면 무한루프에 빠질 수 있다. 예시 @Entity @Table(name = "orders") @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "..
package org.kyhslam.jpa.Post; import javax.persistence.*; import java.util.Date; @Entity public class Post { @Id @GeneratedValue private Long id; private String title; @Lob private String content; @Temporal(TemporalType.TIMESTAMP) private Date created; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(S..
package org.kyhslam.jpa.post; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class Comment { @Id @GeneratedValue private Long id; private String comment; @ManyToOne private Post post; private Integer likeCount; public Integer getLikeCount() { return likeCount; } public void setLikeCount(Int..
JPQL Java Persistence Query Language / Hibernate Query Language 를 의미 데이터베이스 테이블이 아닌, 엔티티 객체 모델 기반으로 쿼리를 작성하는 SQL과 유사한 구문이다. JPA또는 Hibernate가 해당 쿼리를 SQL로 변환해서 실행한다 TypedQuery query = entityManager.createQuery("SELECT p FROM Post AS p", Post.class); List posts = query.getResultList(); posts.forEach(System.out::println); Criteria JPA에서 제공하는 타입 세이프한 쿼리로써 JPQL에서 오타가 났을 경우 이것을 체크하지 못하는 문제를 방지한다. Nativ..
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 publi..