JPA ๋งคํ ์ ๋ณด๋ XML์ด๋ ์ด๋ ธํ ์ด์ ์ค์ ์ ํํด์ ๊ธฐ์ ํ๋ฉด ๋๋ค. ๊ทธ๋ผ XML์ ๋ฌด์์ผ๊น?
XML
XML(eXtensible Markup Language)์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ์ ์ฅํ๋ฉฐ ์ ์กํ๊ธฐ ์ํ ํ์ฅ ๊ฐ๋ฅํ ๋งํฌ์ ์ธ์ด๋ก, HTML๊ณผ ๋น์ทํ์ง๋ง ๋ฏธ๋ฆฌ ์ ์๋ ํ๊ทธ ์์ด ์ฌ์ฉ์๊ฐ ์ง์ ํ๊ทธ๋ฅผ ์ ์ํ์ฌ ๋ฐ์ดํฐ์ ์๋ฏธ์ ๊ตฌ์กฐ๋ฅผ ์ค๋ช ํ๋ค.
์ฌ์ฉ ๋ฐฉ์
JPA์์ XML๋ก ๋งคํ์ ์ฐ๋ ๋ฐฉ์์ ํ์ค์ ์ผ๋ก orm.xml(JPA ORM ๋งคํ ํ์ผ) ์ ๋๊ณ , ์ด๋ฅผ ์คํ๋ง ๋ถํธ/JPA ์ค์ ์ “๋งคํ ๋ฆฌ์์ค”๋ก ๋ฑ๋กํ๋ ํํ์ด๋ค. (์ฆ, ์ด๋ ธํ ์ด์ ๋์ ๋๋ ์ด๋ ธํ ์ด์ ์ “๋ฎ์ด์ฐ๋” ์ฉ๋๋ก XML์ ์ด๋ค.)
1) orm.xml ํ์ผ์ ์ด๋์ ๋๋์?
๊ฐ์ฅ ํํ ๊ธฐ๋ณธ ์์น๋ ์๋์ ๋๋ค.
- src/main/resources/META-INF/orm.xml
์คํ๋ง(JPA ์ค์ )์ ๋ณ๋ ์ง์ ์ด ์์ผ๋ฉด ํด๋์คํจ์ค์์ ๊ธฐ๋ณธ META-INF/orm.xml์ ์ฐพ์ ๋งคํ ๋ฆฌ์์ค๋ก ๋ฑ๋กํ๋ ค๊ณ ์๋ํฉ๋๋ค. ๋ํ orm.xml์ ์คํค๋ง(XSD)๋ Jakarta Persistence ORM ์คํค๋ง๋ฅผ ๋ฐ๋ฆ ๋๋ค.
2) orm.xml์๋ ๋ฌด์์ ์ ๋์?
orm.xml์๋ “์ด๋ค ํด๋์ค๊ฐ ์ด๋ค ํ ์ด๋ธ/์ปฌ๋ผ๊ณผ ๋งคํ๋๋์ง”, “ID๋ ๋ฌด์์ธ์ง”, “์ฐ๊ด๊ด๊ณ/์์ฑ ๋งคํ” ๊ฐ์ ์ํฐํฐ ๋งคํ ์ ๋ณด๋ฅผ XML๋ก ๊ธฐ์ ํฉ๋๋ค(์ด๋ ธํ ์ด์ ์ผ๋ก ํ๋ ๋ด์ฉ์ XML ํ๊ทธ๋ก ์ฎ๊ธฐ๋ ํํ).
๋ํ ์ํฉ์ ๋ฐ๋ผ
- ์ด๋ ธํ ์ด์ + XML ํผ์ฉ(์ผ๋ถ๋ง XML๋ก ์ค๋ฒ๋ผ์ด๋) ๋๋
- XML๋ง ์ฌ์ฉ(์ด๋
ธํ
์ด์
๋ฌด์)
๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ์ด๋ metadata-complete๋ฅผ ์ฌ์ฉํ๋ฉด “์ด XML์ด ์ ๋ถ๋ค(์ด๋ ธํ ์ด์ ์ ๋ณด์ง ๋ง๋ผ)”๋ผ๋ ์๋ฏธ๋ก ๋์ํฉ๋๋ค.
3) ์คํ๋ง ๋ถํธ์์ orm.xml์ “์ฝ๊ฒ” ๋ง๋๋ ๋ฐฉ๋ฒ
์คํ๋ง ๋ถํธ์์๋ ๋ณดํต ์๋ ๋ ์ค ํ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.
๋ฐฉ๋ฒ A) application.yml(๋๋ properties)์ ๋งคํ ๋ฆฌ์์ค ๋ฑ๋ก
์คํ๋ง ๋ถํธ๋ spring.jpa.mapping-resources๋ก persistence.xml์ <mapping-file>๊ณผ ๋์ผํ ์ญํ ์ ํ๋๋ก ์ง์ํฉ๋๋ค.
spring:
jpa:
mapping-resources:
- META-INF/orm.xml
๋ฐฉ๋ฒ B) ๊ธฐ๋ณธ ์์น(META-INF/orm.xml)์ ๋๊ณ ์๋ ํ์ง์ ๋งก๊ธฐ๊ธฐ
๋ช ์ ์ค์ ์ ์ ํด๋, ์คํ๋ง์ JPA ์ค์ ์ ๊ธฐ๋ณธ META-INF/orm.xml์ ์ฐพ์ ๋ฑ๋กํ๋ ค๋ ๋์์ด ์์ต๋๋ค. ๋ค๋ง ํ๋ก์ ํธ ๊ตฌ์ฑ์ ๋ฐ๋ผ ์ค๋ณต ๋ก๋ฉ/๋ฏธ๋ก๋ฉ ์ด์๊ฐ ๋ ์ ์์ด์, ์ด์ ๊ด์ ์์๋ ์์ ๋ฐฉ๋ฒ A์ฒ๋ผ ๋ช ์ํ๋ ๊ฑธ ๋ ๊ถํฉ๋๋ค.
4) (์ฐธ๊ณ ) persistence.xml์ ์ฐ๋ ์ ํต์ ์ธ JPA ๋ฐฉ์์ด๋ผ๋ฉด
persistence.xml์ ๋๋ ๊ตฌ์ฑ(์์ JPA ๋ถํธ์คํธ๋ฉ)์ด๋ผ๋ฉด, ๊ทธ ์์ <mapping-file>๋ก XML ๋งคํ ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ฑ๋กํ ์ ์์ต๋๋ค.
5) ์ด๋ ธํ ์ด์ ์ด๋ ๊ฐ์ด ์ฐ๋ฉด ์ฐ์ ์์๋?
์ผ๋ฐ์ ์ผ๋ก ์ด๋ ธํ ์ด์ ๊ณผ XML์ ๊ฐ์ด ์ฐ๋ฉด ๋ณํฉ๋๊ณ , ์ถฉ๋ ์์๋ XML์ด ์ฐ์ (์ค๋ฒ๋ผ์ด๋) ์ผ๋ก ๋์ํ๋ ๊ตฌ์ฑ์ด ํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ metadata-complete๋ฅผ ์ผ๋ฉด ์ด๋ ธํ ์ด์ ์ ๋ฌด์ํ๋ ์ชฝ์ผ๋ก ๊ฐ๋๋ค.
๋๋ฉ์ธ ๋ชจ๋ธ
๋๋ฉ์ธ ๋ชจ๋ธ์ ์๋น์ค๊ฐ ๋ค๋ฃจ๋ ํ์ค ์ธ๊ณ์ ๊ฐ๋ (ํ์, ์ฃผ๋ฌธ, ๊ฒฐ์ ๊ฐ์ ๊ฒ๋ค)์ ์ํํธ์จ์ด ์์์ ๊ฐ์ฒด์ ๊ด๊ณ๋ก ํํํ ๋ชจ๋ธ์ ๋๋ค. ์ด๋ ์ค์ํ ์ ์ ๋จ์ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ง ๋ง๋๋ ๊ฒ ์๋๋ผ, ๊ทธ ๋ฐ์ดํฐ์ ๋ํ ๋น์ฆ๋์ค ๊ท์น๊ณผ ๋์(ํ๋)๊น์ง ํจ๊ป ๋ด๋ “์ ๋ฌด ์ค์ฌ ๊ฐ์ฒด ๋ชจ๋ธ”์ด๋ผ๋ ๊ฒ๋๋ค.
๋๋ฉ์ธ ๋ชจ๋ธ ์์
- ํ์๊ณผ ์ฃผ๋ฌธ์ ๊ด๊ณ: ํ์์ ์ฌ๋ฌ ๋ฒ ์ฃผ๋ฌธํ ์ ์๋ค. (์ผ๋๋ค)
- ์ฃผ๋ฌธ๊ณผ ์ํ์ ๊ด๊ณ: ์ฃผ๋ฌธํ ๋ ์ฌ๋ฌ ์ํ์ ์ ํํ ์ ์๋ค. ๋ฐ ๋๋ก ๊ฐ์ ์ํ๋ ์ฌ๋ฌ ๋ฒ ์ฃผ๋ฌธ๋ ์ ์๋ค. ์ฃผ๋ฌธ์ํ ์ด๋ผ๋ ๋ชจ๋ธ์ ๋ง๋ค์ด์ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ์ผ๋ค๋, ๋ค๋์ผ ๊ด๊ณ๋ก ํ์ด๋.

"๊ฐ์ฒด์งํฅ์ค๋ฝ์ง ์๋ค"๋ ๋ฌด์จ ์๋ฏธ์ผ๊น?
๊ฐ์ฒด ์ฌ์ด์ ๊ด๊ณ๋ฅผ ๊ฐ์ฒด(์ฐธ์กฐ)๋ก ํํํ์ง ์๊ณ ์ซ์ ID ๊ฐ์ ๊ฐ์ผ๋ก๋ง ๋ค๋ค์, ๋ชจ๋ธ์ด '๊ฐ์ฒด ํ๋ ฅ'์ด ์๋๋ผ '๊ฐ ์กฐ์' ์ค์ฌ์ผ๋ก ํ๋ฌ๊ฐ๋ค๋ ๋ป์ ๋๋ค.
๊ฐ์ฒด์งํฅ์ค๋ฝ์ง ์์ ์ฝ๋ ์์
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
- ๊ด๊ณ๋ฅผ '๊ฐ์ฒด ์ฐธ์กฐ'๊ฐ ์๋๋ผ '์ธ๋ํค ๊ฐ'์ผ๋ก ํํํฉ๋๋ค.
- ์๋ฐ/๊ฐ์ฒด ๊ด์ ์์ "Member๋ Team์ ์ํ๋ค."๋ ๊ด๊ณ๋ ๋ณดํต Member → Team ์ฐธ์กฐ(ํ๋)๋ก ํํํ๋ ๊ฒ ์์ฐ์ค๋ฝ์ต๋๋ค. JPA๋ ์ด๋ฐ "๋จ์ผ ๊ฐ ์ฐ๊ด(association)"์ @ManyToOne์ผ๋ก ํํํ๋๋ก ์ ์ํฉ๋๋ค. ์ฆ, JPA๋ ์๋ "์ฝ๋์์๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ , DB์๋ ๊ทธ ๊ฒฐ๊ณผ๋ก FK๊ฐ ์ ์ฅ๋๊ฒ" ๋ง๋๋ ORM์ ๋๋ค.
- ๋๋ฉ์ธ ๋ชจ๋ธ์ด DB ๊ตฌ์กฐ๋ฅผ ๊ทธ๋๋ก ๋์ด์๊ฒ ๋ฉ๋๋ค.
- teamId๋ ์ฌ์ค์ DB์ FK ํํ์ธ๋ฐ, ์ด๊ฑธ ์ํฐํฐ์ ์ง์ ๋ค๊ณ ์์ผ๋ฉด ๋ชจ๋ธ์ด "๊ฐ์ฒด ๊ด๊ณ"๋ณด๋ค "ํ ์ด๋ธ ์กฐ์ธ/ํค ๊ฐ" ์ค์ฌ์ด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ฒฐ๊ตญ ์๋น์ค ์ฝ๋์์ ๋งค๋ฒ teamId๋ก ๋ค์ ์กฐํํด์ ๋ถ์ด๋ ์์ด ๋๊ณ , ๊ฐ์ฒด๊ฐ ๊ฐ์ฒด๋ต๊ฒ ํ๋ ฅํ๊ธฐ๋ณด๋ค ์ ์ฐพ๊ฑฐ์ผ๋ก ํ๋ฌ๊ฐ๊ธฐ ์ฝ์ต๋๋ค. (JPA๊ฐ ์ ๊ณตํ๋ ค๋ ์ด์ ์ด ์ค์ด๋ญ๋๋ค.)
- ๋ถ์ผ์น/๋ฌด๊ฒฐ์ฑ ๋ฌธ์ ๋ฅผ ๋ง๋ค๊ธฐ ์ฝ์ต๋๋ค.
- teamId๋ ์ซ์์ผ ๋ฟ์ด๋ผ, "์กด์ฌํ์ง ์๋ ํ ID"๋ฅผ ๋ฃ์ด๋ ๊ฐ์ฒด ์์ฒด๋ ๋ง์ง ๋ชปํฉ๋๋ค. ๋ฐ๋ฉด "Team ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ"ํ๋ฉด ๊ด๊ณ๊ฐ ๋ ๋ช ํํด์ง๊ณ , ๋ณ๊ฒฝ ์ง์ ๋ ์ค์ด ๋ชจ๋ธ์ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค. (ํนํ ์๋ฐฉํฅ์ด๋ฉด ํ์ชฝ๋ง ๋ฐ๊ฟ์ ๊ด๊ณ๊ฐ ๊นจ์ง๋ ๋ฌธ์ ๋ฅผ ์ค์ด๋ ค๋ฉด, ๊ด๊ณ ๋ณ๊ฒฝ์ ํ ๋ฉ์๋๋ก ์บก์ํํ๋ ์์ด ์์ฐ์ค๋ฝ์ต๋๋ค.)
๊ทธ๋์ JPA/ORM ๊ด์ ์์ “๊ฐ์ฒด์งํฅ์ค๋ฝ๊ฒ”๋ ๋ณดํต Member๊ฐ teamId๋ฅผ ๊ฐ๋ ๋์ Team์ ์ฐธ์กฐํ๊ฒ ํ๊ณ , JPA๊ฐ ๊ทธ ์ฐธ์กฐ๋ฅผ ์ธ๋ํค๋ก ๋งคํํ๊ฒ ๋๋ ๊ฑธ ๋งํฉ๋๋ค. Hibernate ๋ฌธ์์์๋ FK ๊ด๊ณ๋ @ManyToOne ๊ฐ์ ํ์ค ์ฐ๊ด ๋งคํ์ ์ฐ์ ํ๋ผ๊ณ ์๋ดํฉ๋๋ค.
์ฐธ๊ณ ๋ก, DTO(์์ฒญ/์๋ต)๋ API ๊ฒฝ๊ณ์์๋ ID๋ก ์ฃผ๊ณ ๋ฐ๋ ๊ฒ ์์ฐ์ค๋ฝ์ต๋๋ค. ๋ค๋ง “์ํฐํฐ/๋๋ฉ์ธ ๋ชจ๋ธ ๋ด๋ถ”์์๋ ๊ด๊ณ๋ฅผ ๊ฐ์ฒด ์ฐธ์กฐ๋ก ๋ชจ๋ธ๋งํ๋ ์ชฝ์ด ๋ณดํต ๋ ๊ฐ์ฒด์งํฅ์ ์ด๋ผ๊ณ ํ๊ฐ๋ฉ๋๋ค.
์ฝ๋ ๋ถ์(100L)
Team newTeam = em.find(Team.class, 100L);
- 100L์ ์กฐํํ๋ ค๋ Team ์ํฐํฐ์ "๊ธฐ๋ณธ ํค(PK)"์ ๋๋ค. ์ฆ, @Id๋ก ์ง์ ๋ ๊ฐ์ด 100์ธ ํ์ ์ฐพ์์ค๊ฒ ๋ค๋ ๋ป์ ๋๋ค.
- ๊ทธ๋ฆฌ๊ณ ๋ค์ L์ ์๋ฐ์์ "long ํ์ ๋ฆฌํฐ๋ด" ํ์๋ผ์, 100L์ long(๋ณดํต Long์ผ๋ก ์ฌ์ฉ) ๊ฐ 100์ ์๋ฏธํฉ๋๋ค.
- ์ฐธ๊ณ ๋ก find()๋ ๊ธฐ๋ณธ ํค๋ก ์ํฐํฐ๋ฅผ ์ฐพ๋ ๋ฉ์๋์ด๊ณ , ํด๋น ์ํฐํฐ๊ฐ ์์ผ๋ฉด ๋ณดํต null์ ๋ฐํํฉ๋๋ค.
'๐ Growth > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [TIL] ๊ฐ๋ฐ ๊ธฐ๋ณธ ์ฉ์ด (0) | 2026.04.01 |
|---|---|
| [TIL] 2026๋ 01์ 07์ผ (0) | 2026.01.07 |
| [์คํ๋ง] 2025-07-02 (1) | 2025.07.02 |
| [TIL] 2024๋ 11์ 14์ผ (1) | 2024.11.15 |
| [TIL] 2024๋ 11์ 11์ผ (1) | 2024.11.12 |