<엔티티 설계시 주의점>
#★모든 연관관계는 지연로딩으로 설정★
즉시로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다.
ex) member를 조회할때 연관된 order엔티티까지 한꺼번에 다 조회된다.
최악의 경우에 하나를 조회할때 연관된 모든 것를 DB에서 가져와버림...
뭐 하나 잘못 건들면 연관된 데이터 다 끌고와서 난리남
절대로 쓰지말것
특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다. ->n번 호출된다..
실무에서 모든 연관관계는 지연로딩( LAZY )으로 설정해야 한다.
ex) order 조회할때 order만 가져오게 된다.
연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.
> 실시간으로 원하는것만 가져오는 것
★제발 주의★
@XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야 한다.
ManyToOne (다대일)
- Order, Member
- OrderItem, Order
- Category에서 parent,child
OneToOne
- Order, Delivery
#컬렉션은 필드에서 초기화 하자.
컬렉션은 필드에서 바로 초기화 하는 것이 안전하다.
ex) Order와 Member : Member가 주문을 하면 Member의 orders(list)에 넣어줘야한다 ..당연함
양방향이니까 왔다갔다 할것임..
//Member
//이렇게 선언하기
private List<Order> orders = new ArrayList<>(); //null pointer exception 안나게
하이버네이트는 엔티티를 영속화 할 때, 컬랙션을 감싸서
하이버네이트가 제공하는 내장 컬렉션으로 변경한다.
만약 getOrders() 처럼 임의의 메서드에서 컬력션을 잘못 생성하면
하이버네이트 내부 메커니즘에 문제가 발생할 수 있다.
따라서 필드레벨에서 생성하는 것이 가장 안전하고, 코드도 간결하다.
//이렇게 하지 말것
Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(team); //db에 저장하겠다고 선언 영속성이 생겨서..
//(영속성(persistence)이란? 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성
System.out.println(member.getOrders().getClass());
//출력 결과
class java.util.ArrayList //기존거 이거였는데
class org.hibernate.collection.internal.PersistentBag //값이 바뀌어버림
#cascade, fetch
public class Order {
//생략
@ManyToOne(fetch = LAZY) //order랑 member는 다대일 (서로반대) , 여러개 주문<-하나의 회원
@JoinColumn //매핑을 어떻게 할건지 : 연관관계 주인으로 fk
private Member member; //주문회원
/*
*cascade 안하면
* persist(orderItemA)
* persist(orderItemB)
* persist(orderItemC) 이렇게 해야하함
* 그래서
* persist(order) 로 끝내게
*
*/
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL) //order에 의해서 매핑됐다 , 주인아님
private List<OrderItem> orderItems = new ArrayList<>();
//생략
}
#연관관계 메서드
Order
//원래라면..근데 놓칠 수 도 있으니까
// 밑처럼 원자적으로 묶어버린다
public static void main(String[] args){
Member member = new Member();
Order order = new Order();
member.getOrders().add(order);
order.setMember(member)
}
//==연관관계 메서드== 양방향 연관관계일때/
public void setMember(Member member) {
this.member = member; //member setting할때 order 입장에서 이렇게 멤버를 넣는다
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void setDelivery(Delivery delivery) {
this.delivery = delivery;
delivery.setOrder(this);
}
Category
//자식 여러명 가능
@OneToMany(mappedBy = "parent") // private Category parent; 여기로 이동
private List<Category> child = new ArrayList<>();
//==연관관계 메서드==//
public void addChildCategory(Category child) {
this.child.add(child); //
child.setParent(this); //자식에서도 부모가 누구인지를
'WEB JAVA SPRING > PROJECT' 카테고리의 다른 글
[Day-8] 상품 엔티티, 리파지토리, 서비스 (0) | 2023.08.25 |
---|---|
[Day-7] 회원 도메인, 리포지토리, 서비스, 회원 기능 테스트 (0) | 2023.08.25 |
[Day-5] 엔티티 클래스 개발2 (0) | 2023.08.25 |
[Day-4] 도메인 모델과 테이블 설계, 엔티티 클래스 개발 1 (0) | 2023.08.25 |
[Day-3] JPA와 DB설정, 동작확인 (0) | 2023.08.25 |