엔티티를 영구 저장하는 환경
어플리케이션이 DB에서 꺼내온 데이터 객체를 보관하는 역할.
영속성 컨텍스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관, 관리
비영속(New)
영속(Managed)
준영속(Detached)
삭제(Removed)
1차캐시를 둔다면?
1. find("memberB")와 같은 로직이 있을 때 먼저 1차 캐시 조회
2. 있으면 해당 데이터 반환
3. 없으면 그 때 실제 DB로 "SELECT * FROM..."의 쿼리를 내보냄
4. 그리고 반환하기 전에 1차 캐시에 저장 후 반환
-> memberB를 find하는 요청이 다시 들어와도 굳이 DB로 가지 않아도 됨.
@Entity 관련
1. 기본 생성자는 필수.
2. final 클래스, enum, interface 등에는 사용 불가
3. 저장할 필드라면 final을 사용하면 안된다.
@Table 관련
@Column 관련
1. 객체 필드를 테이블 컬럼에 매핑하는데 사용
2. 생략 가능
3. 속성들은 자주 쓸 일이 없고, 보통 생략도 한다.
@Enumerated 관련
1. Java Enum을 테이블에서 사용한다고 생각하면 좋다.
2. 속성으로는 Ordinal, String.
String - 해당 문자열 그대로 저장해 비용이 많이 들지만, 나중에 Enum이 변경되어도 위험할 일이 없어 일반적으로 String 많이 사용
@ManyToOne
@JoinColumn(name="food_id")
DB의 외래키는 양방향에서 조회 가능
외래키는 연관관계가 있는 두개의 테이블 중 하나의 테이블만 있으면 충분.
두 객체 연관관계 중 하나를 정해 테이블의 외래키 관리 -> 연관관계의 주인
연관관계의 주인만이 DB 연관관계와 매핑되고 외래키를 관리(등록, 수정, 삭제)하게 되어있음.
반면, 주인이 아닌 쪽은 읽기만 할 수 있다.
연관관계의 주인을 정한다는 것은 외래키 관계자를 선택하는 것.
연관관계의 주인에는 값을 입력하지 않고, 주인이 아닌 곳에만 값을 입력하면 문제
객체 관점에서 양쪽 방향에 모두 값을 입력해주는 것이 가장 안전.
양쪽 방향 모두 값을 입력하지 않으면 JPA를 사용하지 않는 순수한 객체 상태에서 심각한 문제 발생.
엔티티를 조회시 연관된 엔티티들이 항상 사용 x
JPA는 필요없는 DB조회를 줄이며 성능을 최적화.
이런 문제를 해결하려고 엔티티가 실제 사용될 때 까지 DB 조회를 지연하는 방법을 제공
-> 지연로딩
지연로딩 기능을 사용하려면 실제 엔티티 객체 대상에 DB 조회를 지연할 수 있는 가짜 객체가 필요한데, 이걸 프록시 객체라고한다.
엔티티를 조회할 때 연관된 엔티티도 함께 조회
@ManyToOne(fetch = FetchType.EAGER)
연관된 엔티티를 실제 사용할 때 조회한다
@ManyToOne(getch = FetchType.LAZY)
기본적으로 "즉시로딩"은 연관된 엔티티를 조인해 다 긁어온다
"지연로딩"은 실제로 가짜 객체를 이용시, 그때 별도의 쿼리가 나간다..
즉시로딩은 연관관계가 많고 복잡할수록 비용이 기하급수적으로 늘어나 지연로딩을 걸어두는게 일반적!
기본값
@ManyToOne, @OneToOne : 즉시 로딩(FetchType.EAGER)
@OneToMany, @ManyToMany : 지연 로딩(FetchType.LAZY)
그렇다면 굳이 필요가 없다면, 앞으로 코딩시
@ManyToOne(FetchType.Lazy)로 걸어주는게 좋다...
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이기능을 사용하면 된다.
JPA는 cascade 옵션으로 영속성 전이를 제공
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
private List