JPA1/Section.2(인프런,김영한) 리뷰

김민석·2023년 5월 9일
0

JPA

목록 보기
2/4

도메인 분석 및 설계

우선 인프런강의에서 진행하는 예제의 기능 및 요구사항은 다음과 같다
다음은 다이어그램이다
실제로 회원이 여러 상품을 구매할 수 있는 것 처럼 회원, 주문, 상품 간의 관계에서 일대다 혹은 다다대 관계를 확인 할 수 있다.

하지만 다대다 관계는 거의 사용하지 않으므로 주문상품이라는 엔티티를 추가해서 다대다가 아닌 일대다 관계로 풀어 냈다.

테이블로 표현을 하면 다음과 같다.

연관관계는 그림에서 새발표기법으로 표기를 잘 해놓았다.

왜래키 값을 업데이트할 때에는
일대다 일때 다 에 왜래키가 들어감
주인의 값이 바뀌면 왜래 키 값도 바꾼다.
왜래키 값을 가까운걸 주인으로 하는게 좋음
주인이라고해서 비즈니스 상 우위에 있는것은 아님
(member(주인)-> member_id(FK))
mappedBy="(~~)" 나는 ~~에 의해 매핑됨 =>읽기 전용으로 됨

**코드 참고

Entity 설계 주의점

1.Setter사용 줄이기

Setter가 너무 많이 열려 있다면 변경포인트가 너무 많아 유지보수가 힘들다

2.모든 연관 관계는 지연로딩으로 설정

즉시 로딩은 예측하기 쉽지 않고 하나를 로딩하면 연관되어 있는 다른 데이터까지 같이 로딩이 되기 때문에 (N+1문제 발생)
LAZY키워드를 사용해서 지연로딩으로 설정하는게 좋다.
fetch join을 사용하면 원하는 것만 가져올 수 있다.

3.collection은 필드에서 바로 초기화 하는 것이 안전하다.

Ex))Member에 26번째줄
private List orders =new ArrayList<>();
=>바로 초기화
public Member() {
orders= new ArrayList<>();
=>따로 초기화
}

따로 만들어서 초기화 하는것이 NULL 문제로 부터 자유롭다.
NULLPOINTEXCEPTION 날 일이 없고 , 컬랙션을 감싸서 hibernate가 제공하는 내장 컬렉션으로 변경한다

하지만 바로 초기화하면 hibernate가 추적하기위해 member 객체를 자신의 타입에 알맞게 바꾸는데
ex) class org.hibernate.collection.internal.PersistentBag
그러나 public Member() {
orders= new ArrayList<>(); =>따로 초기화
}
이런식으로 다시 초기화 해버리면 hibernate가 원하는 매커니즘 대로 동작하지 않아 문제발생할 우려가 있다.

4.cascade

부모 Entity를 persist할 때 자식 entity도 함께 persist 하고 싶을 때 이용한다.

이로 인해서 부모와 자식의 persist, remove 를 함께 관리할 수 있다.
또한 부모 entity 만으로 자식 entity들을 모두 컨트롤할 수 있다.

ex) persist(orderItemA)persist(orderItemB)persist(orderItemC)
persist(order)쓸 것을 만일 Cascade를 쓰면 persist(order)만 쓰면 된다.
각각 호출 해야하지만 한꺼번에 가능.

단, 반드시 Entity 서로 간의 단일 종속관계가 있을 때만 사용하고, 다른 Entity 와 복잡하게 매핑관계가 얽혀 있다면 사용하면 안된다.

5.연관관계 편의 메서드

양방향 관계일때 Member, Order의 경우 서로의 값을 세팅해 주기 위해 사용
예)

member.getOrders().add(order);
order.setMember(member);
↓
member.getOrders().add(this);

한 줄로 처리 가능

연관 관계의 주인의 반대쪽 필드는 mappedby를 설정하여 읽기 전용으로 쓰게 된다.
그런데 일대다 중 다 쪽에만 연관 관계를 설정하면 객체 지향적이지 않을뿐더러, DB에서 데이터를 조회하기 전까지는 일대다 중 다 쪽에만 값이 세팅되어 일 쪽 Entity에서는 연관 관계를 모르기 때문에 일 쪽의 값을 출력해보면 데이터가 나오지 않을 수 있다.

0개의 댓글