Spring JPA 기본 개념

말하는 감자·2025년 3월 31일

내일배움캠프

목록 보기
32/73

영속성 - persistence

영속성은 한글로보면 뭔소린가 싶다

Spring JPA에서 "영속성(Persistence)"데이터를 저장하고 유지하는 성질을 의미한다.
즉, 단어 해석처럼 엔티티를 영구적으로 저장해주는 환경!!을 의미함.






영속성 컨텍스트 - Persistence Context

Entity 객체를 영속성 상태로 관리하는 일종의 캐시 역할을 하는 공간으로 여기에 저장된 Entity는 데이터베이스와 자동으로 동기화되며 같은 트랜잭션 내에서는 동일한 객체가 유지된다.

위는 강의에서 나온 정의

쉽게 말하면, "JPA 내부의 저장소" 라고 생각하면 된다.

JPA를 사용하면, 엔티티 객체를 직접 데이터베이스에서 가져오고, 저장하고, 수정하는 것이 아니라 영속성 컨텍스트를 통해 관리된다.
즉, 객체가 메모리에 올라와 있는 상태를 관리하는 공간이다.

트랜잭션이 끝나기 전에 같은 객체를 여러 번 조회해도 DB에 다시 조회하지 않고, 영속성 컨텍스트에서 가져올 수 있음!!

🍋Entity 객체

데이터베이스에서 Entity란 저장할 수 있는 데이터의 집합을 의미한다.

영속성 컨텍스트의 4가지 상태

이런 영속성 컨텍스트는 4가지 상태를 가질 수 있다.

1️⃣비영속(new/transient)

  • 영속성 컨텍스트가 모르는 새로운 상태
  • 데이터베이스와 전혀 연관이 없는 객체

2️⃣영속(managed)

  • 영속성 컨텍스트에 저장되고 관리되고 있는 상태
  • 데이터베이스와 동기화되는 상태

3️⃣준영속(detached)

  • 영속성 컨텍스트에 저장되었다가 분리되어 더 이상 기억하지 않는 상태

4️⃣삭제(removed)

  • 영속성 컨텍스트에 의해 삭제로 표시된 상태
  • 트랜잭션이 끝나면 데이터베이스에서 제거





🎮 4가지 상태 비유 예시 ( 게임 캐릭터 )

뭐가 좋을지 고민하다가 극단적 k-게이머 관점으로 풀어봤다.
영속성 컨텍스트 = 길드
객체(Entity) = 유저

1️⃣ 비영속 상태 (new / transient)

  • 아직 길드에 가입하지 않음 (데이터베이스에 저장된 기록 없음)
  • 게임을 종료하면 더 이상 정보가 남아있지 않음
  • 길드 입장에서는 이 유저가 있는지 없는지 모르고 연관도 없는 유저임
    아직 길드에 가입하지 않은 유저

2️⃣ 영속 상태 (managed)

  • 게임 서버에서 유저를 길드 멤버로 관리하고 있음
  • 길드 공지, 길드 버프 등 모든 기능을 정상적으로 받을 수 있음
    유저가 길드에 가입된 상태

4️⃣ 준영속 (detached)

  • 원래 길드에 소속되어 있었는데 길드에서 탈퇴함

  • 하지만 캐릭터는 살아있고, 다시 길드에 가입할 수도 있음

    • (길드에서 강퇴되었다고 캐릭터가 삭제되는 건 아니니까)

    길드에서 탈퇴했지만, 캐릭터는 그대로 존재하는 상태


5️⃣ 삭제 상태 (removed)

  • 캐릭터를 삭제
  • 완전히 데이터베이스에서 사라짐, 복구 불가
  • 인벤토리도, 레벨도, 퀘스트 진행도 전부 삭제됨
  • 길드 입장에서도 더이상 이 유저를 찾을 수 없음
    캐릭터 삭제 버튼을 눌러서 영구 삭제됨





영속성 컨텍스트의 4가지 주요 특징

❤️ 1차 캐시
🧡 동일성 보장 (Identity)
💛 쓰기 지연 (Write-behind / Delayed Write)
💚 변경 감지 (Dirty Checking)

📌 영속성 컨텍스트 정리

  • 데이터베이스에 즉시 반영하지 않고 먼저 영속성 컨텍스트에서 관리
  • 영속성 컨텍스트에서 관리하는 객체(Entity)들은 메모리(❤️ 1차 캐시)에 올라가 있어서 필요할 때 데이터베이스 접근 없이 바로바로 가져올 수 있음!
  • 같은 엔티티를 두 번 조회해도 새로 만들지 않고 기존 객체를 재사용!
    • 항상 같은 객체(인스턴스)를 반환함! (🧡 동일성 보장)
  • 트랜잭션이 끝날 때 이때까지 저장해놓은 쿼리문이 한꺼번에 데이터베이스에 저장됨! (💛쓰기 지연)
    • 저장되기 전에 데이터베이스와 영속성 컨텍스트의 객체의 차이점을 자동으로 비교해줌!! ( 바뀐게 없으면 굳이 수정안하겠찌 = 💚변경 감지(Dirty Checking)로 수정된 내용만 업데이트)






Entity 만들기

@Entity

클래스에 @Entity가 있다면 JPA가 관리하는 Entity로 만들어진다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="test"> <!-- createEntityManagerFactory에서 사용할 이름 -->
        <class>org.entity.Tutor</class>
        <properties>
            <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <!-- DB 아이디 -->
            <property name="jakarta.persistence.jdbc.user" value="root"/>
            <!-- DB 비밀번호 -->
            <property name="jakarta.persistence.jdbc.password" value="1111"/>
            <!-- 스키마 -->
            <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sparta"/> 
						<!-- 스키마 자동생성 속성 -->
            <property name="hibernate.hbm2ddl.auto" value="create" />
						
						<!-- Hibernate가 DB에 전송하는 DDL, DML SQL을 콘솔에 출력한다. -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            
            <!-- 한꺼번에 전송될 SQL 수량 설정 -->
<!--            <property name="hibernate.jdbc.batch_size" value="10"/>-->
        </properties>
    </persistence-unit>
	</persistence>





사용 어노테이션

@Entity

@Entity(name = "Tutor") // 기본 값, name 속성은 생략하면 클래스 이름이 된다.
...
public class Tutor {
  • JPA를 사용하여 객체를 테이블과 매핑할 때 사용한다.(필수)
  • 필수 값 : PK 값(@Id 사용), 기본 생성자
  • 사용불가 키워드 : final, enum, interface, inner 클래스 / 필드에 final 키워드
  • 속성
    • name
      • Entity 이름 지정
      • 기본 값은 클래스 이름과 같다.
      • 기본 값을 주로 사용하니 안써도 무방!!

@Table

@Table(name = "tutor")
public class Tutor {
}
  • 속성
    • name
      • Entity와 매핑할 테이블 이름을 지정
      • 기본 값은 Entity 이름(Tutor)을 사용
    • catalog
      • 데이터베이스 catalog 매핑
    • schema
      • 데이터베이스 schema 매핑
    • uniqueConstraints
      • DDL 생성 시 유니크 제약 조건 설정
@Table(uniqueConstraints = {@UniqueConstraints
				(
					name = "name_unique", 
					columnNames= {"name"}
				)
		}
)

유니크 제약 조건은 이런식으로 사용함
(DDL을 자동으로 생성할 때만 사용되며 Application 로직에는 영향이 없음)

profile
대충 데굴데굴 굴러가는 개발?자

0개의 댓글