JPA 양방향 연관관계 설정 Best Practice

박경희·2025년 4월 28일
0

공부를 해보자

목록 보기
38/40

Kotlin + Spring Data JPA로 예배/콘티 관리 서비스를 개발 중.
Conti와 Song 관계:

하나의 Conti에는 여러 개의 Song이 포함됨

즉, Conti 1 : N Song


잘못된 코드: 관계가 불완전한 경우

val conti = Conti(...)
val song = Song(..., conti = conti)
conti.songs.add(song)

contiRepository.save(conti) // DetachedEntityException 발생 가능

문제점

  • Song.conti를 생성자에서 바로 넣었지만,

  • conti는 아직 영속화(persist)되지 않은 상태

  • Hibernate 입장에서 song이 detached 객체를 참조하고 있다고 판단 → 에러 발생


반드시 지켜야 할 패턴

  1. 연관 관계의 주인은 @ManyToOne → 즉, Song.conti
@Entity
data class Song(
    ...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "conti_id")
    var conti: Conti? = null
)
  1. Conti에서 편의 메서드로 양방향 연결을 책임짐
@Entity
data class Conti(
    ...
) {
    @OneToMany(mappedBy = "conti", cascade = [ALL], orphanRemoval = true)
    val songs: MutableList<Song> = mutableListOf()

    fun addSong(song: Song) {
        songs.add(song)
        song.conti = this //  ⭐️ 꼭 있어야 함 ⭐️
    }
}

왜 이렇게 해야 하나?

  • JPA는 연관관계의 주인만 DB에 반영함 → @ManyToOne이 주인

  • 연관관계를 양방향으로 완성하려면 두 객체 모두 참조가 필요

  • 이를 위해 addSong() 메서드에서 song.conti = this 해줘야 함

  • 실무에서는 removeSong(), clearSongs()까지 관리하는 구조가 일반적

0개의 댓글

Powered by GraphCDN, the GraphQL CDN