삶 가운데 남긴 기록 AACII.TISTORY.COM
JPA 다대일(Many to One) 연관관계 본문
JPA 연관관계 결정
데이터베이스에서는 PK와 FK으로 엔티티간 관계를 표현합니다.
반면 JPA는 객체 지향이라서 데이터 연관관계의 방향성을 결정하는 것이 어렵습니다.
예를 들어, 회원이 여러 개의 아이템을 가지고 있다고 가정하면, 회원 객체가 아이템들을 참조할 것인지, 아이템이 회원을 참조할 것인지 판단해야 합니다.
JPA는 보통 변화가 많은 쪽을 기준으로 결정하거나 ERD에서 FK를 기준으로 결정합니다.
변화가 많은 쪽 기준
회원과 게시물의 관계를 예를 들면, 회원들이 활동을 통해 여러 게시물이 만들어지므로 연관 관계는 게시물 기준으로 판단하는 것이 좋습니다.
| 회원 아이디 | 회원 이름 |
| user1 | 사용자1 |
| user2 | 사용자2 |
| user3 | 사용자3 |
| user4 | 사용자4 |
| 번호 | 제목 | 작성자 | 내용 |
| 1 | 제목1 | 사용자1 | 내용...1 |
| 2 | 제목2 | 사용자2 | 내용...2 |
| 3 | 제목3 | 사용자3 | 내용...3 |
반대로 회원을 기준으로 시작하면 나중에 엔티티 클래스 설계를 감당 못할 만큼 연관 관계가 필요하게 됩니다.
예를 들어 회원이 게시물을 작성하고 게시물에 여러 파일과 댓글이 달리고 각 게시글에 좋아요 기능 추가되면 결국 회원 중심으로 이루어지는 시스템을 설계하게 됩니다.
ERD(엔티티 관계 다이어 그램) 에서 JPA의 연관 관계를 읽을 때 FK를 판단하는 것이 좋습니다.
단방향과 양방향
관계형 데이터베이스와 객체 지향의 다른 점은 객체가 다른 객체를 참조하는 방식이 다르다는 점입니다.
관계형 데이터베이스는 특정한 PK를 다른 테이블에서 FK로 참조해서 사용합니다.
하지만 객체지향에서는 A객체(데이터)가 B객체(데이터)의 참조를 가질수도 있고 B객체가 A객체의 참조를 가질 수 있습니다.
JPA는 객체 지향을 통해 관계형 데이터베이스를 처리하므로 참조를 결정 할 때 다양한 방식이 존재 할 수 있습니다.
A객체가 B객체를 참조하거나 B객체가 A를 참조하는 한쪽 방향으로만 참조를 유지하는 방식을 단방향(unidirectional)이라고 하고 양쪽 모두 참조하는 방식을 양방향(bidirectional)이라고 부릅니다.
단방향은 구현이 단순하고 에러 발생 여지를 줄일 수 있지만 조인 처리 같은 다른 엔티티 내용을 사용하는 작업이 어렵습니다.
양방향은 양쪽 객체를 모두 관리해야 하는 불편함이 있지만 JPA에서 필요한 데이터를 탐색하는 작업에서는 편리합니다.
보통 기본적으로 단방향 참조 관계를 유지하면서 다른 엔티티를 사용할 때는 JPQL을 통해 처리를 합니다.
게시판과 댓글 관련 예제
import jakarta.persistence.*;
import lombok.*;
/**
* 댓글 관리용 Entity.
* 이 클래스가 데이터베이스 테이블과 매핑되는 '엔티티'임을 선언해서 JPA가 이 클래스를 관리하게 됨.
* 기본적으로 클래스 이름과 테이블 이름은 같지만 @Table(name="") 어노테이션으로 테이블 이름을 지정할 수 있음.
* @ToString할 때 참조 객체를 사용하지 않도록 exclude 속성값으로 board 객체를 지정.
* @ManyToOne같은 연관 관계를 나타낼 때는 반드시 fetch 속성을 LAZY으로 지정.
* 프로젝트 실행시 Reply관련 테이블이 자동으로 생성 됨.
* 생성된 테이블에서는 Board 관련 속성으로 board_bno 이름의 컬럼이 생성되고 자동으로 FK가 생성 됨.
*/
@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = "board")
public class Reply extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long rno; //rno 를 댓글 테이블에서 사용할 PK(id) 컬럼으로 지정
@ManyToOne(fetch = FetchType.LAZY)
private Board board; //Reply Entity(댓글)는 Board Entity(게시글)와 다대일 관계
private String replyText;
private String replyer;
}

'DEV&OPS > Java' 카테고리의 다른 글
| 인텔리제이 주석 템플릿 설정 (0) | 2026.07.06 |
|---|---|
| FreeMarker 설정과 기본 사용법 (0) | 2026.07.06 |
| spring mvc / jsp 페이징 처리 (0) | 2025.11.07 |
| Spring MVC 다국어 처리 (0) | 2025.11.05 |
| Spring 3 Quartz 1.8.6 스케줄링 (0) | 2025.11.05 |
