본문 바로가기
JPA

양방향 관계 맵핑

by 박성민 2021. 5. 20.

먼저 연관관계의 주인을 선정해야 한다.
단순하게 외래 키를 관리하는 쪽이 주인이다.
즉 ManyToOne 관계일 경우 Many쪽이 주인이다.

이제 차량 출고 도메인과 결제 수단 도메인으로 예시로 정리해보겠다.
차량을 출고하면 결제수단은 현금 or 카드 or 현금+카드일 수 있다.
따라서 출고와 결제수단은 1대 다의 관계를 갖는다.

결제수단 도메인(Payment)

@ManyToOne(fetch = LAZY, cascade = ALL)
@JoinColumn(name = "release_id")
private Release release;
  • @ManyToOne: 다대1관계, 결제수단이 외래키를 관리한다.
  • @JoinColumn(name = "release_id"): Release 도메인의 ID 필드 column명을 명시한다.

출고 도메인(Release)

@OneToMany(mappedBy = "release", cascade = ALL)
private List<Payment> payments = new ArrayList<>();
  • @OneToMany: 결제수단 도메인과 1대다 관계
  • mappedBy = "release": 주인이 아닌 쪽에서 반드시 설정해야하며 주인 도메인에 맵핑된 필드명을 명시해야 한다.

출고 로직

ReleaseSaveRequestDto

public Release toEntity() {
    List<Payment> payments = new ArrayList<>();
    for (PaymentRequestDto requestDto : this.payments) {
        payments.add(requestDto.toEntity());
    }

    return Release.builder()
            .staff(staff)
            .salesStaff(salesStaff)
            .price(price)
            .deposit(deposit)
            .status(status)
            .payments(payments)
            .build();
}
  • 결제 수단 DTO를 결제수단 도메인으로 변경 후 Release 도메인에 담아서 리턴한다.

Payment

public void create(Release release) {
    this.release = release;
}
  • 결제수단 도메인에 출고 도메인을 담는다.

Release

public void create(Car car) {
    car.release(this.releaseDate);
    this.car = car;

    for (Payment payment : payments) {
        payment.create(this);
    }
}
  • 출고시 결제수단의 create 메서드를 호출해준다.
  • 이렇게 하면 Payment와 Release가 서로를 맵핑하게 된다.

ReleaseService

Release release = requestDto.toEntity();
release.create(car);

return new ReleaseSaveResponseDto(releaseRepository.save(release));
  • 양쪽 모두 맵핑이 완료된 후 출고 도메인을 save한다.

테스트 결과

Release 테이블

1

Payment 테이블

2

  • RELEASE_ID 맵핑 확인

댓글