JPA

[JPA] 9. 연관관계 매핑 - 일대다(1 : N)

inuma 2021. 1. 11. 00:18
프로젝트 git url github.com/rtef23/JpaStudy
필요 1. docker
2. docker-compose
프로젝트 정보 mysql : 5.7 - docker image
java : 1.8

일대다(1 : N), '일'이 연관관계의 주인의 경우

  • @OneToMany
    • mappedBy ; 연관관계의 주인 필드를 선택한다.
    • fetch ; 글로벌 페치 전략을 설정한다.
    • cascade ; 영속성 전이 기능을 사용한다.
    • targetEntity ; 연관된 엔티티의 타입 정보를 설정한다.
  • 추천하는 연관관계는 아니다.
@Entity
@Table(name = "USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long id;

  @Column(name = "username")
  private String username;
  
  ...
}

@Entity
@Table(name = "TEAM")
public class Team {
  @Id
  @GeneratedValue
  @Column(name = "team_id")
  private Long id;

  @Column(name = "name")
  private String name;

  @OneToMany
  @JoinColumn(name = "team_id")
  private List<User> users = new ArrayList<>();
  
  ...
}
  • @JoinColumn 어노테이션 사용이 필요하다 (사용하지 않는 경우, 중간 매핑 테이블이 생기게 된다.)
  • 엔티티가 관리하는 외래키가 다른 테이블에 있음
  • 연관관계 관리를 위해 추가로 Update SQL이 전송되게 된다.

 

  • Team 엔티티에 Member를 추가하고 Member와 Team에 persist api를 사용하면
    DB에는 insert user, insert member, update user 총 3개의 쿼리가 전송되게 된다.

 

  • 일대다의 관계에서 양방향 매핑
    • 공식적으로는 존재하지 않음
    • @JoinColumn(insertable=false, updatable=false)
    • 읽기 전용필드를 사용하여 양방향처럼 사용하는 방법
    • 가급적 다대일 양방향 매핑을 사용하는 것을 추천
@Entity
@Table(name = "USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long id;

  @Column(name = "username")
  private String username;

  @ManyToOne
  @JoinColumn(name = "team_id", insertable = false, updatable = false)
  private Team team;
  
  ...
}

@Entity
@Table(name = "TEAM")
public class Team {
  @Id
  @GeneratedValue
  @Column(name = "team_id")
  private Long id;

  @Column(name = "name")
  private String name;

  @OneToMany
  @JoinColumn(name = "user_id")
  private List<User> users = new ArrayList<>();
  
  ...
}