๐ŸŒฑ TIL - JPA์™€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ

์กฐํ˜œ์€ยท2026๋…„ 4์›” 6์ผ

Java

๋ชฉ๋ก ๋ณด๊ธฐ
5/10
post-thumbnail

JPA์™€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

Spring Boot์—์„œ JPA๋ฅผ ๋ฐฐ์šฐ๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ๊ฐ€์žฅ ์ž์ฃผ ๋“ฃ๋Š” ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋‹ค.
์ฒ˜์Œ์—๋Š” ๊ทธ๋ƒฅ Entity๋ฅผ ์ €์žฅํ•ด๋‘๋Š” ๊ณต๊ฐ„ ์ •๋„๋กœ๋งŒ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์ •๋ฆฌํ•ด๋ณด๋‹ˆ JPA์˜ ํ•ต์‹ฌ ๋™์ž‘ ๋Œ€๋ถ€๋ถ„์ด ์ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์—ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” JPA๊ฐ€ ๋ฌด์—‡์ธ์ง€, ๊ทธ๋ฆฌ๊ณ  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์™œ ์ค‘์š”ํ•œ์ง€๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

๐Ÿ“ JPA๋ž€?

JPA๋Š” Java Persistence API์˜ ์•ฝ์ž๋‹ค.
์ž๋ฐ”์—์„œ ORM ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ‘œ์ค€ ๋ช…์„ธ๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.
์—ฌ๊ธฐ์„œ ORM์€ ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

์ฆ‰, ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ฒฐํ•ด์„œ ๊ฐ์ฒด ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ฐฉ์‹์ด๋‹ค.

์˜ˆ์ „์ฒ˜๋Ÿผ JDBC๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‹ค์Œ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ–ˆ๋‹ค.

  • SQL ์ง์ ‘ ์ž‘์„ฑ
  • ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ
  • ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜

๋ฐ˜๋ฉด JPA๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Entity์™€ ํ…Œ์ด๋ธ”์„ ๋งคํ•‘ํ•ด๋‘๊ณ , ๊ฐ์ฒด๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ ๋กœ JPA๋Š” ๊ตฌํ˜„์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ช…์„ธ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ๋กœ๋Š” Hibernate ๊ฐ™์€ ๊ตฌํ˜„์ฒด๊ฐ€ JPA๋ฅผ ๋™์ž‘ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
hibernate๊ฐ€ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ด๋‹ค.

๐ŸŠ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ž€?

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋Š” Entity ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ณต๊ฐ„์ด๋‹ค.

JPA๋Š” DB์— ๋ฐ”๋กœ SQL์„ ๋‚ ๋ฆฌ๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ, ์ค‘๊ฐ„์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‘๊ณ  Entity๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฐ”๋กœ EntityManager๋‹ค.

  • EntityManager : Entity๋ฅผ ์ €์žฅ, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œํ•˜๋Š” ์—ญํ•  ์ˆ˜ํ–‰
  • EntityManagerFactory : EntityManager๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณต์žฅ ์—ญํ•  ์ˆ˜ํ–‰

์ฒ˜์Œ์—” ๊ทธ๋ƒฅ DB์— ๋ฐ”๋กœ ์ €์žฅํ•˜๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€? ์‹ถ์—ˆ๋Š”๋ฐ, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— JPA๋Š” ๋‹จ์ˆœ CRUD๋ฅผ ๋„˜์–ด์„œ ์—ฌ๋Ÿฌ ํŽธ๋ฆฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

  • 1์ฐจ ์บ์‹œ
  • ์“ฐ๊ธฐ ์ง€์—ฐ
  • ๋ณ€๊ฒฝ ๊ฐ์ง€

๐Ÿ‹ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ 

1. 1์ฐจ ์บ์‹œ

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ๋‚ด๋ถ€์—๋Š” 1์ฐจ ์บ์‹œ๊ฐ€ ์žˆ๋‹ค.

Entity๋ฅผ ์กฐํšŒํ•˜๋ฉด ์ด ์บ์‹œ์— ์ €์žฅ๋˜๊ณ , ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ๊ฐ™์€ Entity๋ฅผ ๋‹ค์‹œ ์กฐํšŒํ•  ๋•Œ๋Š” DB๋ฅผ ๋‹ค์‹œ ์กฐํšŒํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜จ๋‹ค.

์ฒ˜์Œ ์กฐํšŒํ•  ๋•Œ๋Š” DB ์ ‘๊ทผ, ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ๋‹ค์‹œ ์กฐํšŒํ•  ๋•Œ๋Š” ์บ์‹œ์—์„œ ๋ฐ˜ํ™˜

์ด ๊ธฐ๋Šฅ์˜ ์žฅ์ ์€ ๋‹จ์ˆœํžˆ ์กฐํšŒ ์„ฑ๋Šฅ๋งŒ์ด ์•„๋‹ˆ๋‹ค.
๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ๋Š” ๊ฐ™์€ Entity๋ฅผ ๋‹ค์‹œ ์กฐํšŒํ–ˆ์„ ๋•Œ ๊ฐ์ฒด ๋™์ผ์„ฑ๋„ ๋ณด์žฅ๋œ๋‹ค.

์ฆ‰, ๊ฐ’๋งŒ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ •๋ง ๊ฐ™์€ ๊ฐ์ฒด๋กœ ๊ด€๋ฆฌ๋œ๋‹ค๋Š” ์ ์ด ์ค‘์š”ํ•˜๋‹ค.

2. ์“ฐ๊ธฐ ์ง€์—ฐ

JPA๋Š” persist()๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ INSERT SQL์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ผ๋‹จ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— Entity๋ฅผ ์ €์žฅํ•˜๊ณ , ์‹คํ–‰ํ•  SQL์€ ๋‚ด๋ถ€์— ๋ชจ์•„๋‘”๋‹ค. ๊ทธ๋ฆฌ๊ณ  flush() ๋˜๋Š” ํŠธ๋žœ์žญ์…˜ commit ์‹œ์ ์— ํ•œ ๋ฒˆ์— DB๋กœ ๋ณด๋‚ธ๋‹ค.

ใ„ด> ์ด๊ฑธ ์“ฐ๊ธฐ ์ง€์—ฐ์ด๋ผ๊ณ  ํ•œ๋‹ค.

์ฒ˜์Œ์—๋Š” ์ €์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ๋Š”๋ฐ ์™œ DB์— ๋ฐ”๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”์ง€ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„๋กœ SQL์„ ๋ชจ์•„์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ , ์ค‘๊ฐ„์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ํ•œ ๋ฒˆ์— rollback ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ์ •ํ•ฉ์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์‹์ด๋‹ค.

3. ๋ณ€๊ฒฝ ๊ฐ์ง€

JPA์—์„œ ์ •๋ง ์‹ ๊ธฐํ–ˆ๋˜ ๋ถ€๋ถ„์ด ๋ฐ”๋กœ ๋ณ€๊ฒฝ ๊ฐ์ง€๋‹ค.

JPA๋Š” ์˜์† ์ƒํƒœ์˜ Entity๋ฅผ ์กฐํšŒํ•  ๋•Œ, ์ฒ˜์Œ ์ƒํƒœ๋ฅผ ์Šค๋ƒ…์ƒท์ฒ˜๋Ÿผ ์ €์žฅํ•ด๋‘”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŠธ๋žœ์žญ์…˜ commit ์‹œ์ ์— ํ˜„์žฌ ์ƒํƒœ์™€ ๋น„๊ตํ•ด์„œ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด UPDATE SQL์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.

-> ์ง์ ‘ update() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

User user = em.find(User.class, 1L);
user.setName("๋ณ€๊ฒฝ๋œ ์ด๋ฆ„");

์ด๋ ‡๊ฒŒ ๊ฐ’๋งŒ ๋ฐ”๊ฟ”๋„, ํŠธ๋žœ์žญ์…˜์ด commit ๋  ๋•Œ JPA๊ฐ€ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•ด์„œ UPDATE SQL์„ ์‹คํ–‰ํ•œ๋‹ค.
-> ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ Entity๋ฅผ ๊ณ„์† ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๐Ÿ‡ Entity ์ƒํƒœ

JPA์—์„œ Entity๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€์˜ ๊ด€๊ณ„์— ๋”ฐ๋ผ ์ƒํƒœ๊ฐ€ ๋‚˜๋‰œ๋‹ค.

๋น„์˜์†(Transient)

new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šคํ™”๋œ Entity ๊ฐ์ฒด.
์•„์ง ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋ผ JPA์˜ ๊ด€๋ฆฌ๋ฅผ ๋ฐ›์ง€ ์•Š์Œ.

์˜์†(Managed)

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์–ด JPA๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ƒํƒœ

  • ๋น„์˜์† โ†’ ์˜์†: persist()

์ค€์˜์†(Detached)

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์ €์žฅ๋˜์–ด ๊ด€๋ฆฌ๋˜๋‹ค๊ฐ€ ๋ถ„๋ฆฌ๋œ ์ƒํƒœ. ๋”์ด์ƒ ๋ณ€๊ฒฝ ๊ฐ์ง€ x

  • ์˜์† โ†’ ์ค€์˜์†: detach(entity), clear(), close()
  • ์ค€์˜์† โ†’ ์˜์†: merge(entity)

    merge()๋Š” ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์ƒํƒœ๋ฅผ ๋ณต์‚ฌํ•œ ์ƒˆ๋กœ์šด ์˜์† ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•จ.

์‚ญ์ œ(Removed)

์‚ญ์ œํ•˜๊ธฐ๋กœ ํ‘œ์‹œ๋œ ์ƒํƒœ. ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ DELETE SQL ์‹คํ–‰๋จ.

  • remove(entity)

Entity ์ƒํƒœ๋ฅผ ๋ณด๋ฉด ๊ฒฐ๊ตญ ํ•ต์‹ฌ์€ ํ•˜๋‚˜๋‹ค.
์˜์† ์ƒํƒœ์ผ ๋•Œ๋งŒ JPA๊ฐ€ Entity๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

์ฆ‰,1์ฐจ ์บ์‹œ, ์“ฐ๊ธฐ ์ง€์—ฐ, ๋ณ€๊ฒฝ ๊ฐ์ง€ ๋ชจ๋‘ ์˜์† ์ƒํƒœ์˜ Entity๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

๐Ÿ‰ Spring Boot์—์„œ์˜ JPA์™€ ํŠธ๋žœ์žญ์…˜

Spring Boot์—์„œ๋Š” JPA ์‚ฌ์šฉ์— ํ•„์š”ํ•œ ์„ค์ •์„ ๋งŽ์ด ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

  • application.properties ๋˜๋Š” application.yml์— DB ์ •๋ณด๋ฅผ ์„ค์ •ํ•˜๋ฉด JPA ํ™˜๊ฒฝ์ด ๊ตฌ์„ฑ๋จ.
  • EntityManagerFactory, EntityManager๋„ ์ž๋™ ์„ค์ •๋จ.
  • @PersistenceContext๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด EntityManager๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
@PersistenceContext
private EntityManager em;

๊ทธ๋ฆฌ๊ณ  Spring์—์„œ๋Š” @Transactional์„ ์‚ฌ์šฉํ•ด์„œ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ •์ƒ ์ข…๋ฃŒ ์‹œ commit, ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ rollback ๋˜๋Š” ๊ตฌ์กฐ๋‹ค.

@Transactional
public void save() {}

๋ณดํ†ต ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์—์„œ๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ์•ˆ์—์„œ ํ•จ๊ป˜ ๋™์ž‘ํ•œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ โ†’ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ โ†’ ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ

์ด ํ๋ฆ„์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

๊ทธ๋ž˜์„œ ๋ณ€๊ฒฝ ๊ฐ์ง€๋„ ๊ฒฐ๊ตญ ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋Š” ์‹œ์ ๊ณผ ์—ฐ๊ฒฐ๋˜๊ณ , ์“ฐ๊ธฐ ์ง€์—ฐ๋„ commit ์‹œ์ ๊ณผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐ๋œ๋‹ค.

๐Ÿ‘ ์ •๋ฆฌ

์ด๋ฒˆ์— JPA๋ฅผ ์ •๋ฆฌํ•˜๋ฉด์„œ ๋А๋‚€ ๊ฑด, JPA๋Š” ๋‹จ์ˆœํžˆ SQL์„ ๋Œ€์‹  ์จ์ฃผ๋Š” ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ๋Š” ์ ์ด๋‹ค.

ํ•ต์‹ฌ์€ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด Entity๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๊ณ , ๊ทธ ๋•๋ถ„์— ๊ฐ™์€ Entity๋ฅผ ์บ์‹œ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  SQL ์‹คํ–‰์„ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ณ  ๊ฐ์ฒด ๊ฐ’ ๋ณ€๊ฒฝ๋งŒ์œผ๋กœ UPDATE๋ฅผ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋‹ค

์ฆ‰, JPA์˜ ํŽธ๋ฆฌํ•จ์€ ๊ฒฐ๊ตญ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๊ฐ€ Entity๋ฅผ ๊ด€๋ฆฌํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ๊ธฐ๋Šฅ๋“ค์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์•ž์œผ๋กœ JPA๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‹จ์ˆœํžˆ save()๋‚˜ find() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋งŒ ๋ณด๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์ง€๊ธˆ ์ด Entity๊ฐ€ ์–ด๋–ค ์ƒํƒœ์ธ์ง€, ๊ทธ๋ฆฌ๊ณ  ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์•ˆ์—์„œ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ๊ฐ™์ด ์ƒ๊ฐํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ๋А๊ผˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€