
์ผ๊ธฐ ๋๋ฉ์ธ์ 'ํ๋ ์นดํ ๊ณ ๋ฆฌ' ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ฉด์, ํ ์ด๋ธ ์ค๊ณ๋ถํฐ JPA ์ํฐํฐ ๋งคํ๊น์ง ์ ์ฒด ๊ณผ์ ์ ๊ธฐ๋กํด ๋ณด๋ ค๊ณ ํ๋ค.
์ฒ์์๋ ๋จ์ํ๊ฒ Enum์ผ๋ก ์ฒ๋ฆฌํ๋ ค ํ๋๋ฐ, ๊ณ ๋ฏผ์ ๊ฑฐ๋ญํ ์๋ก ๊ตฌ์กฐ๊ฐ ์ ์ ์ปค์ก๋ค ...
๐จ ๊ณ ๋ฏผ ๋ฐฐ๊ฒฝ
์ผ๊ธฐ์ 'ํ๋ ์นดํ ๊ณ ๋ฆฌ'๋ฅผ ๋งคํํ๋ ๊ธฐ๋ฅ์ ๊ธฐํํ๋ค.
์๋ฅผ ๋ค์ด ํ๋์ ์ผ๊ธฐ์ "๋ฐ์ดํธ", "์ ๋ฌด", "์ฝ์" ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ถ์ผ ์ ์์ด์ผ ํ๋ค.
1. ์นดํ ๊ณ ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ด๋ฆฌํ ๊ฒ์ธ๊ฐ?
2. ์ผ๊ธฐ์ ์นดํ ๊ณ ๋ฆฌ์ ๊ด๊ณ๋ฅผ ์ด๋ป๊ฒ ์ค์ ํ ๊ฒ์ธ๊ฐ?
3. JPA ์ฐ๊ด๊ด๊ณ ๋งคํ์ ์ด๋ป๊ฒ ํด์ผ ํ๋๊ฐ?
โก๏ธ ํ๋ํ๋ ํ์ด๋ณด๋ ์๊ฐ๋ณด๋ค ๊ณ ๋ คํ ๊ฒ ๋ง์๋ค.
๐ค ๊ณ ๋ฏผํ๋ ์ ํ์ง
1. ์นดํ ๊ณ ๋ฆฌ ๋ฐ์ดํฐ ๊ด๋ฆฌ ๋ฐฉ๋ฒ : Enum vs DB ํ ์ด๋ธ
A. Enum์ผ๋ก ๊ด๋ฆฌ
enum class ActivityCategory {
FAMILY_EVENT, DATE, WORK, FRIENDS_MEETING, ALONE_TIME
}
์์๋ก ๊ด๋ฆฌํ ๊ฒฝ์ฐ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํ์ง๋ง, ์ถํ ์ ์ ๋ณ ์ปค์คํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ค๋ฉด ๊ธฐ์กด ๋ก์ง ์์ ์ด ๋ง์ด ๋ฐ์ํ๋ค
B. DB ํ ์ด๋ธ๋ก ๊ด๋ฆฌ
์ ์ ๋ณ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ ํ์ฅ์ด ์์ ๋กญ์ง๋ง, ํ ์ด๋ธ ์ค๊ณ๊ฐ ๋ณต์กํด์ง๋ค๋ ๋จ์ ์ด ๋ฐ์ํ๋ค.
2. ๊ด๊ณ ์ค์ : 1:N vs M:N
์ฒ์์๋ '์ผ๊ธฐ ํ๋์ ์นดํ ๊ณ ๋ฆฌ ํ๋'๋ผ๊ณ ๊ธฐํ์ ํ์๋๋ฐ,
์๊ฐํด๋ณด๋ ํ๋ฃจ์ ์ฌ๋ฌ ํ๋๋ค์ ํ ๊ฒ์ ๊ณ ๋ คํด์ 'ํ๋์ ์ผ๊ธฐ์ ์ฌ๋ฌ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๋งคํ'๋๋ ๊ฒ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
์ผ๊ธฐ 1๊ฐ → ์นดํ
๊ณ ๋ฆฌ N๊ฐ
์นดํ
๊ณ ๋ฆฌ 1๊ฐ → ์ผ๊ธฐ N๊ฐ
โก๏ธ `M:N(๋ค๋๋ค)` ๊ด๊ณ์๋ ์ค๊ฐ ํ ์ด๋ธ์ด ํ์ํ๋ฏ๋ก, DiaryActivityCategory ํ ์ด๋ธ์ ๋์ ํ๊ธฐ๋ก ํ๋ค.
๐ ์ต์ข ํ ์ด๋ธ ์ค๊ณ
ํ๋ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ
ActivityCategory
โโโ id (PK)
โโโ name (์นดํ
๊ณ ๋ฆฌ ์ด๋ฆ)
โโโ user_id (FK, nullable)
`user_id`๊ฐ null์ด๋ฉด ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ null์ด ์๋๋ฉด ํด๋น ์ ์ ๊ฐ ์ถ๊ฐํ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ๋ก ๊ตฌ๋ถํ๋ค.
MVP ๋จ๊ณ์์๋ ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ๋ง ์ฌ์ฉํ์ง๋ง, ๋์ค์ ์ปค์คํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋ผ๋ ๊ตฌ์กฐ๋ฅผ ๋ฐ๊ฟ ํ์๊ฐ ์๋ค.
์ค๊ฐ ํ ์ด๋ธ
DiaryActivityCategory
โโโ id (PK)
โโโ diary_id (FK, NOT NULL)
โโโ activity_category_id (FK, NOT NULL)
โโโ UNIQUE(diary_id, activity_category_id) ← ๋ณตํฉ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด
โ ๋ณตํฉ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด์ ๊ฑธ์ด์, ๊ฐ์ ์ผ๊ธฐ์ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ์ค๋ณต ๋งคํ๋๋ ๊ฒ์ DB ๋ ๋ฒจ์์ ๋ฐฉ์งํ๋ค.
์ ์ฒด ๊ด๊ณ ์์ฝ
User ← ActivityCategory (1:N ๋จ๋ฐฉํฅ)
User ← Diary (1:N ๋จ๋ฐฉํฅ)
Diary ↔ DiaryActivityCategory ↔ ActivityCategory (M:N, ์ค๊ฐ ํ
์ด๋ธ)
๐ JPA ์ฐ๊ด๊ด๊ณ ๋งคํ
ActivityCategory → User

๋ฐฉํฅ : ๋จ๋ฐฉํฅ
FK ์์น : ActivityCategory์ user_id
์ฃผ์ธ : ActivityCategory
๋งคํ : `@ManyToOne` + `@JoinColumn`
Diary → User

๋ฐฉํฅ : ๋จ๋ฐฉํฅ
FK ์์น : Diary์ user_id
์ฃผ์ธ : Diary
๋งคํ : `@ManyToOne` + `@JoinColumn`
Diary ↔ DiaryActivityCategory


๋ฐฉํฅ : ์๋ฐฉํฅ
FK : DiaryActivityCategory์ diary_id
์ฃผ์ธ : DiaryActivityCategory
๋งคํ : ์ฃผ์ธ์ `@JoinColumn`, ๋ฐ๋๋ `mappedby`
ActivityCategory → DiaryActivityCategory

๋ฐฉํฅ : ๋จ๋ฐฉํฅ
FK : DiaryActivityCategory์ activity_category_id
์ฃผ์ธ : DiaryActivityCategory
๋งคํ : `@ManyToOne` + `@JoinColumn`
โก๏ธ FK๋ฅผ ์ค์ ๋ก ๊ฐ์ง๊ณ ์๋ ์ชฝ์ด ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ(owning side)์ด๋ค.
๐ @JoinColumn์ ์๋ฏธ
๋ด๊ฐ ํ๋ ์คํด : `@JoinColumn(name = "...")` = ์๋ ํ ์ด๋ธ์ PK โ
์ค์ ์๋ฏธ: `@JoinColumn(name = "...")` = ๋ด ํ ์ด๋ธ์ ์๋ FK ์ปฌ๋ผ์ ์ด๋ฆ โ
class DiaryActivityCategory(
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "diary_id", nullable = false) // โฌ
๏ธ DiaryActivityCategory ํ
์ด๋ธ์ diary_id ์ปฌ๋ผ
val diary: Diary,
)
์๋ฐฉํฅ ๋งคํ: ์ฃผ์ธ vs mappedBy
// DiaryActivityCategory (์ฃผ์ธ) - FK๋ฅผ ์ง์ ๊ด๋ฆฌ
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "diary_id", nullable = false)
val diary: Diary,
// Diary (๋ฐ๋์ชฝ) — DiaryActivityCategory์ diary ํ๋๋ฅผ ๋ฐ๋ผ๊ฐ
@OneToMany(mappedBy = "diary", orphanRemoval = true, cascade = [CascadeType.ALL])
var diaryActivityCategories: MutableList<DiaryActivityCategory> = mutableListOf()
protected set
โก๏ธ `mappedBy = "diary"`๋ DiaryActivityCategory ์ํฐํฐ์ `diary` ํ๋๋ช ์ ๊ฐ๋ฆฌํจ๋ค. ์ปฌ๋ผ๋ช ์ด ์๋๋ค!