TIL - 26.01.07

이준연·2026년 1월 7일

학습 키워드


  • JPA 연관관계 매핑

JPA 연관관계 매핑


연관관계란

엔티티(테이블) 간의 관계를 의미합니다.

예시

  • 학생과 학급: 한 학급에는 여러 학생이 있고, 한 학생은 하나의 학급에 속합니다.
  • 주문과 상품: 한 주문에는 여러 상품이 있을 수 있습니다.
  • 회원과 팀: 한 팀에는 여러 회원이 있고, 한 회원은 하나의 팀에 속합니다.

연관관계의 주인

단방향 관계에서 연관관계의 주인은 경우의 수가 하나 밖에 없습니다. 다른 쪽을 필드로 갖고 있는 엔티티 클래스가 하나 뿐이기 때문입니다.

💡쉽게 말해서 @ManyToOne을 가진 엔티티가 연관관계의 주인입니다. 그리고 @ManyToOne은 수가 많은 쪽 즉, 학생과 학급 중 학생이 필드로 가지고 있어야 합니다.

JPA 조회 전략(FetchType)

FetchType은 JPA가 하나의 엔티티를 조회할 때, 그 엔티티와 연관된 다른 엔티티를 언제 데이터베이스에서 함께 조회할지를 결정하는 옵션입니다.

  • FetchType.EAGER(즉시 로딩): 이름 그대로 부모 엔티티를 조회하면, 연관된 자식 엔티티까지 한 번에 모두 조회합니다.
  • FetchType.LAZY(지연 로딩): 실제로 데이터가 필요한 시점에 DB에서 조회합니다.

💡FetchType.LAZY를 사용하여 필요한 데이터를 선택하여 사용하는 것이 좋다!

양방향 관계 단방향으로 풀어 작성하기

@Getter
@Entity
@Table(name = "authors")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Author {
	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	private Long id;
 	private String name;
}
@Getter
@Entity
@Table(name = "books")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Book {
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	private Long id;
 	private String title;
}
@Getter
@Entity
@Table(name = "book_author")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class BookAuthor {
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	private Long id;
 	@ManyToOne
 	@JoinColumn(name = "book_id")
	private Book book;
 	@ManyToOne
 	@JoinColumn(name = "author_id")
  	private Author author;
}

💡 두 개의 엔티티의 고유 식별자를 모두 가지고 있는 별개의 엔티티를 생성하여 양방향 관계를 구현할 수 있다.

@ManyToOne 옵션

  • 항상 FetchType.LAZY를 사용하여 선택권을 가져오자!
  • FK가 필수가 아니라면 Optional=false & nullable=false를 사용
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "team_id", nullable = false)
private Team team;
profile
반갑습니다!

0개의 댓글