@Entity
class User {
@ManyToOne
@JoinColumn(name = "team_id")
var team: Team? = null
}
@Entity
class Team {
@OneToMany(mappedBy = "team")
val users: MutableList<User> = mutableListOf()
}
(FK)를 실제로 DB에 반영하는 쪽을 의미@JoinColumn이 선언된 엔티티가 주인 객체누가 관계를 주도하는가를 기준으로 한쪽에 둠Order.addItem(item) → Order - OrderItem 관계방식1) Team이 직접 FK 세팅
@Entity
class Team {
@OneToMany(mappedBy = "team", cascade = [Cascade.ALL], orphanRemoval = true)
val users: MutableList<User> = mutableListOf()
fun addUser(user) {
users.add(user)
user.team = this
}
}
@Entity
class User {
@ManyToOne
@JoinColumn(name = "team_id")
var team: Team? = null
}
방식2) 주인 객체에만 FK 세팅 두고 호출
@Entity
class Team {
@OneToMany(mappedBy = "team", cascade = [CascadeType.ALL], orphanRemoval = true)
val users: MutableList<User> = mutableListOf()
fun addUser(user) {
users.add(user)
user.changeTeam(this)
}
}
@Entity
class User {
@ManyToOne
@JoinColumn(name = "team_id")
var team: Team? = null
fun changeTeam(team) {
this.team = team
}
}
두 방식의 비교
| 구분 | Team이 직접 FK 세팅 | 주인 객체(User)에서 FK 세팅 |
|---|---|---|
| 코드 간결성 | ✅ 직관적, 짧음 | ⭕ 약간 길어지지만 크게 차이 없음 |
| 중복 방지 | ❌ 다른 엔티티에서 FK 세팅 로직 중복 발생 | ✅ FK 변경 로직 한 곳(User)에서만 관리 |
| 유지보수성 | ❌ FK 변경 규칙 수정 시 모든 호출부 수정 필요 | ✅ 주인 객체 메서드만 수정하면 전역 적용 |
| 도메인 의미 반영 | ⭕ "팀이 멤버를 모은다" 표현 자연스러움 | ⭕ "팀이 멤버를 모은다" + 주인 객체 규칙 준수 |
| 확장성 | ❌ 관계 늘어나면 중복 폭발 | ✅ 확장 시에도 변경 최소화 |