JPA(3)

9mond·2023년 10월 11일
0
post-thumbnail

1. 양방향 연관관계

  • 현재 예제의 객체는 Member가 Team을 가졌으나, Team은 Member를 가지지 못했다.

2. 객체와 테이블이 관계를 맺는 차이

2-1. 테이블 연관관계가 1개일 때

  • 회원 <-> 팀의 연관관계 1개(양방향)
    -> MEMBER 테이블 입장에서 TEAM 테이블 조인 가능
    -> TEAM 테이블 입장에서 MEMBER 테이블 조인 가능

2-2. 객체 연관관계가 2개일 때

  • 회원 -> 팀 연관관계 1개(단방향)
  • 팀 -> 회원 연관관계 1개(단방향)
    -> 사실은 단방향 연관관계가 2개 있는 것이다.
    -> 억지로 양방향이라고 말하는 것.

3. 둘 중 하나로 외래키를 관리해야 한다.

  • Member에서 Team으로 가는 team 참고값과 Team에서 Member로 가는 members 참고값이 있다.
  • Member에서 Team값이 수정 됐을 때 MEMBER table의 TEAM_ID가 수정이 되야 하는지,
    Team에 있는 members를 수정했을 때 MEMBER에 있는 TEAM_ID가 수정이 되야 하는지?
    => DB입장에서는 MEMBER에 있는 TEAM_ID만 update가 되면 된다.

4. 연관관계 주인(Owner)

  • 양방향 매핑 규칙
  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관관계 주인만이 외래 키를 관리할 수 있다.(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성이 사용되지 않은 쪽
    -> mappedBy : '내가 누군가에 의해서 mapping이 되었다' 라는 뜻
  • 주인이 아니면 mappedBy 속성으로 주인을 지정
  • mappedBy가 적힌 곳은 읽기만 가능하다.
  • 값을 넣어도 아무일도 벌어지지 않는다.
  • 대신 조회는 가능

5. 주의사항

  • JpaMain02에 insert문만 실행되고, select문은 실행되지 않았다.
  • team이 영속성 컨텍스트에 들어가 있는데, 현재는 member가 할당되지 않은 상태에서 team으로 검색을 하니 1차 캐시에 담겨있는 내용 그대로가 조회된 것.
  • 즉, 영속성 컨텍스트 영역 사용 시 team을 중심으로 member의 조회가 되지 않는다.
  • 순수 객체 상태를 고려해서 항상 양 쪽에 값을 설정하자
    -> 연관관계 편의 메서드를 생성
  • 양방향 매핑 시 무한 루프를 조심해야 한다.
    -> toString(), lombok

6. 연관관계 편의 메서드 생성

  • N(다)에 넣기 : Member에 추가

  • 1(일)에 넣기 : Team에 추가



Member<->Order

양방향 매핑


Order<->OrderItem


OrderItem<->Item


7. 양방향 매핑 정리

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료
  • 양방향 매핑은 반대 방향으로 조회 기능이 추가된 것 뿐
  • 양방향 사용 이유 : JPQL에서 역방향으로 탐색할 일이 많아서다.
  • 단방향 매핑을 잘하고(fk를 잘 걸어주는 것), 양방향은 필요할 때 추가해도 됨(테이블에 영향을 주지 않음. 기능에 대한 추가)

8. 연관관계의 주인을 정하는 기준

  • 비즈니스 로직을 기준으로 연관관계 주인을 선택하면 안됨.
  • 연관관계의 주인은 외래 키의 위치를 기준으로 정해야 함.

9. 임베디드 타입

  • 새로운 값 타입을 직접 정의할 수 있다.
  • JPA는 임베디드 타입(embedded type)이라고 한다.
  • 주로 기본 값 타입을 모아 만들어서 복합값 타입이라고도 한다.

9-1. JPA에서 임베디드 타입 사용법

  • @Embeddable : 값 타입을 정의하는 곳에 표시
  • @Embedded : 값 타입을 사용하는 곳에 표시
  • 기본 생성자 필수

9-2. 임베디드 타입의 장점

  • 재사용이 높아짐
  • 높은 응집도
  • Period.isWork()처럼 해당 값 타입만 사용하는 의미있는 메서드를 만들 수 있다.
    -> 객체 지향적 설계가 가능하다.
  • 임베디드 타입을 포함한 모든 값 타입은 값 타입을 소유한 엔티티 생명주기를 의존한다.

9-3. 임베디드 타입과 테이블 매핑

  • 임베디드 타입은 엔티티의 값일 뿐이다.
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 객체와 테이블을 아주 세밀하게 매핑하는 것이 가능하다.
  • 잘 설계한 ORM어플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.

9-4. @AttributeOverride : 속성 재정의

  • 한 엔티티에서 같은 값 타입을 사용하려면 컬럼 명이 중복
  • @AttributeOverride, @AttributeOverrides를 사용해서 컬럼 명 속성을 재정의

9-5. 객체 타입의 한계

  • 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 있다.
  • 문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.
  • 자바 기본 타입에 값을 대입하면 값을 복사한다.
  • 객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.
  • 객체의 공유 참조는 피할 수 없다.
profile
개발자

0개의 댓글

관련 채용 정보