Home > Spring > πŸƒ[Spring] JPA 연관관계에 λŒ€ν•œ 좔가적인 κΈ°λŠ₯λ“€μ—λŠ” 무엇이 μžˆμ„κΉŒμš”? - 연관관계 μ‚¬μš©μ‹œ 주의점.

πŸƒ[Spring] JPA 연관관계에 λŒ€ν•œ 좔가적인 κΈ°λŠ₯λ“€μ—λŠ” 무엇이 μžˆμ„κΉŒμš”? - 연관관계 μ‚¬μš©μ‹œ 주의점.
Spring Framework

πŸƒ[Spring] JPA 연관관계에 λŒ€ν•œ 좔가적인 κΈ°λŠ₯λ“€μ—λŠ” 무엇이 μžˆμ„κΉŒμš”? - 연관관계 μ‚¬μš©μ‹œ 주의점.

  • JPAμ—μ„œ 연관관계λ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” μ—¬λŸ¬κ°€μ§€ μ£Όμ˜ν•΄μ•Ό ν•  사항이 μžˆμŠ΅λ‹ˆλ‹€.

1️⃣ μ—°κ΄€κ΄€κ³„μ˜ 주인 μ„€μ •.

  • μ—°κ΄€κ΄€κ³„μ—μ„œ 주인과 비주인을 μ˜¬λ°”λ₯΄κ²Œ μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    • 주인이 μ•„λ‹Œ μͺ½μ—μ„œ 연관관계λ₯Ό μˆ˜μ •ν•΄λ„ λ°μ΄ν„°λ² μ΄μŠ€μ—λŠ” λ°˜μ˜λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, 관계 주인을 λͺ…ν™•νžˆ μ§€μ •ν•˜κ³  주인을 톡해 관계λ₯Ό 관리해야 ν•©λ‹ˆλ‹€.
      • 예λ₯Ό λ“€μ–΄, μ–‘λ°©ν–₯ μ—°κ΄€κ΄€κ³„μ—μ„œ mappedBy 속성을 μ œλŒ€ν˜Έ μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ λΆˆν•„μš”ν•œ 쿼리가 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ 지연 λ‘œλ”©(Lazy Loading)κ³Ό μ¦‰μ‹œ λ‘œλ”©(Eager Loading).

  • μ—°κ΄€λœ μ—”ν‹°ν‹°λ₯Ό μ–Έμ œ λ‘œλ“œν• μ§€μ— 따라 μ„±λŠ₯이 크게 영ν–₯을 받을 수 μžˆμŠ΅λ‹ˆλ‹€.
    • FetchType.LAZYλŠ” ν•„μš”ν•œ μ‹œμ μ— 데이터λ₯Ό λ‘œλ“œν•˜μ§€λ§Œ, FatchType.EAGERλŠ” μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•  λ•Œ μ¦‰μ‹œ μ—°κ΄€λœ λͺ¨λ“  데이터λ₯Ό λ‘œλ“œν•˜λ―€λ‘œ, ν•„μš” μ΄μƒμ˜ 데이터λ₯Ό 가져와 μ„±λŠ₯이 μ €ν•˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.
      • 예λ₯Ό λ“€μ–΄, @OneToMany κ΄€κ³„μ—μ„œ EAGER λ‘œλ”©μ„ μ‚¬μš©ν•˜λ©΄ μ˜ˆμƒν•˜μ§€ λͺ»ν•œ λŒ€λŸ‰μ˜ 쿼리가 λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

3️⃣ λ¬΄ν•œ 루프 문제.

  • μ–‘λ°©ν–₯ 연관관계λ₯Ό JSON으둜 직렬화할 λ•Œ, μ„œλ‘œ μ°Έμ‘°ν•˜λŠ” 객체듀이 계속 ν˜ΈμΆœλ˜λ©΄μ„œ λ¬΄ν•œ 루프가 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ @JsonIgnore λ˜λŠ” @JsonManagedReference / @JsonBackReference 같은 μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•΄ 직렬화 λŒ€μƒμ—μ„œ μ œμ™Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μŠ€ν”„λ§κ³Ό 같은 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 이λ₯Ό μ²˜λ¦¬ν•˜μ§€ μ•ŠμœΌλ©΄ λ¬΄ν•œ 루프가 λ°œμƒν•˜μ—¬ μ„œλ²„κ°€ 쀑단될 수 μžˆμŠ΅λ‹ˆλ‹€.

4️⃣ 연관관계 맀핑 μ‹œ 데이터 무결성 주의.

  • μ—”ν‹°ν‹°μ˜ μƒνƒœκ°€ μΌκ΄€λ˜λ„λ‘ 연관관계 μ–‘μͺ½μ„ λͺ¨λ‘ μ„€μ •ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, μ–‘λ°©ν–₯ κ΄€κ³„μ—μ„œ ν•œμͺ½λ§Œ 관계λ₯Ό μ„€μ •ν•˜λ©΄ λ‹€λ₯Έ μͺ½μ—μ„œλŠ” 관계가 μ—†λŠ” κ²ƒμœΌλ‘œ 읡식될 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 두 엔티티에 λŒ€ν•΄ μ–‘λ°©ν–₯ 관계λ₯Ό μ„€μ •ν•  λ•ŒλŠ”, μ–‘μͺ½ ν•„λ“œλ₯Ό λͺ¨λ‘ μ„€μ •ν•˜λŠ” 핼퍼 λ©”μ„œλ“œλ₯Ό λ§Œλ“œλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.
    public void setUserProfile(UserProfile profile) {
      this.userProfile = profile;
      profile.setUser(this);
    }
    

5️⃣ Cascade μ˜΅μ…˜ μ‚¬μš© 주의.

  • CascadeType μ˜΅μ…˜(CascadeType.PERSIST, CascadeType.REMOVE λ“±)을 μ‚¬μš©ν•  λ•ŒλŠ”, 자칫 λΆˆν•„μš”ν•˜κ²Œ μ—°κ΄€λœ λͺ¨λ“  μ—”ν‹°ν‹°κ°€ μ˜μ†ν™”λ˜κ±°λ‚˜ μ‚­μ œ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
    • μ—°κ΄€λœ λͺ¨λ“  μ—”ν‹°ν‹°λ₯Ό ν•œ λ²ˆμ— μ˜μ†ν™”ν•˜κ±°λ‚˜ μ‚­μ œν•  λ•Œλ§Œ μ‹ μ€‘νžˆ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
      • 예λ₯Ό λ“€μ–΄ CascadeType.REMOVEλ₯Ό 잘λͺ» μ„€μ •ν•˜λ©΄ λΆ€λͺ¨ μ—”ν‹°ν‹° μ‚­μ œ μ‹œ μ—°κ΄€λœ μžμ‹ 엔티티도 λͺ¨λ‘ μ‚­μ œλ  수 μžˆμŠ΅λ‹ˆλ‹€.

6️⃣ N + 1 문제.

  • μ¦‰μ‹œ λ‘œλ”©(FetchType.EAGER)을 μ‚¬μš©ν•  λ•Œ N+1 문제λ₯Ό μœ λ°œν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, λΆ€λͺ¨ μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•  λ•Œ μžμ‹ μ—”ν‹°ν‹°λ₯Ό 맀번 μ‘°νšŒν•˜λ©΄, 좔가적인 쿼리가 λ°œμƒν•΄ μ„±λŠ₯에 큰 영ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€.
      • 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ JPQL의 fetch join을 μ‚¬μš©ν•˜μ—¬ ν•„μš”ν•œ 데이터λ₯Ό ν•œ λ²ˆμ— μ‘°νšŒν•˜κ±°λ‚˜, @BatchSize 같은 μ˜΅μ…˜μ„ κ³ λ €ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

7️⃣ 데이터 λ³€κ²½ μ‹œ 주의.

  • JPAλŠ” μ—”ν‹°ν‹°λ₯Ό μΆ”μ ν•˜λŠ” 1μ°¨ μΊμ‹œλ₯Ό 가지고 μžˆμ–΄ μ—”ν‹°ν‹°λ₯Ό λ³€κ²½ν•˜λ©΄ μžλ™μœΌλ‘œ λ°μ΄ν„°λ² μ΄μŠ€μ— λ°˜μ˜λ©λ‹ˆλ‹€.
    • 이λ₯Ό μ΄μš©ν•œ μžλ™ 반영 κΈ°λŠ₯은 νŽΈλ¦¬ν•˜μ§€λ§Œ, ν•œ νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ 같은 μ—”ν‹°ν‹°λ₯Ό μ—¬λŸ¬ 번 μ‘°νšŒν•˜κ±°λ‚˜ λ³€κ²½ν•  경우, 데이터 정합성이 깨지지 μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

8️⃣ λ³΅μž‘ν•œ 연관관계 섀계 μ‹œ 신쀑함.

  • λ§Žμ€ 연관관계가 λ³΅μž‘ν•˜κ²Œ μ–½νžˆλ©΄ μ„±λŠ₯에 λ¬Έμ œκ°€ 생길 수 있고, μ½”λ“œμ˜ μœ μ§€ λ³΄μˆ˜μ„±μ΄ λ–¨μ–΄μ§‘λ‹ˆλ‹€.
    • 상황에 따라 λΆˆν•„μš”ν•œ μ—°κ΄€κ΄€κ³„λŠ” μ œκ±°ν•˜κ³  β€œλ‹¨λ°©ν–₯ 관계”λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.
  • λ³΅μž‘ν•œ 연관관계λ₯Ό λ‹¨μˆœν™”ν•˜κ³ , μ—°κ΄€λœ μ—”ν‹°ν‹° μ‘°νšŒκ°€ ν•„μš”ν•  λ•Œλ§Œ 쿼리λ₯Ό μˆ˜ν–‰ν•˜λ„λ‘ μ„€κ³„ν•˜λ©΄ μ„±λŠ₯κ³Ό μœ μ§€λ³΄μˆ˜μ„±μ΄ ν–₯μƒλ©λ‹ˆλ‹€.

9️⃣ μš”μ•½.

  • 연관관계 주인을 μ •ν™•νžˆ μ„€μ •ν•˜κ³ , λ¬΄ν•œ λ£¨ν”„μ˜ 데이터 무결성을 μ£Όμ˜ν•©λ‹ˆλ‹€.
  • 지연 λ‘œλ”©μ„ 기본으둜 ν•˜κ³ , ν•„μš”μ— 따라 μ¦‰μ‹œ λ‘œλ”©κ³Ό 페치 쑰인을 μ‚¬μš©ν•©λ‹ˆλ‹€.
  • N+1 문제λ₯Ό λ°©μ§€ν•˜λ©°, Cascade μ˜΅μ…˜μ€ μ‹ μ€‘νžˆ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • λ³΅μž‘ν•œ μ—°κ΄€κ΄€κ³„λŠ” ν”Όν•˜κ³  λ‹¨μˆœν™”ν•  수 μžˆλŠ” ꡬ쑰λ₯Ό μ„ νƒν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.