Spring Data JPA의 큰 그림을 봤다면, 이제 진짜로 DB와 연결되는 코드를 작성하게 된다.
그 시작점이 바로 엔티티(Entity) 다.
이 글에서는:
- 엔티티가 정확히 뭔지
- 왜 DTO랑 구분해야 하는지
- @Entity, @Id, @GeneratedValue가 각각 무슨 역할인지
- 왜 기본 생성자를 protected로 두는지
를 지금 단계에서 필요한 만큼만 정리한다.
1. 엔티티(Entity)란
: 엔티티는 DB 테이블과 1:1로 매핑되는 “도메인 객체”다.
- JPA가 직접 관리하는 객체
- DB의 한 row ↔ 자바 객체 하나
- 저장/조회/수정의 대상
⇒ 엔티티는 DB의 데이터를 자바 객체로 다루기 위한 도메인 표현이며, JPA는 조회 결과를 엔티티 객체로 생성하기 때문에 기본 생성자가 필요하다. 이 생성자는 JPA만 사용할 수 있도록 보통 protected로 제한한다.
예를 들면:
- users 테이블 ↔ User 엔티티
- orders 테이블 ↔ Order 엔티티
2. 엔티티 vs DTO
이 둘은 역할이 완전히 다르다.
DTO (Data Transfer Object)
- 계층 간 데이터 전달용
- 요청/응답 바디에 쓰임
- 단순 데이터 묶음
- JPA 관리 대상 아님
public record UserCreateRequest(String email, String password) {}
Entity
- 도메인 자체
- DB 상태와 연결됨
- JPA가 추적/관리
- 비즈니스 규칙을 가질 수 있음
@Entity
public class User {
...
}
👉 엔티티 = DB 모델,
👉 DTO = 통신용 포장지
이렇게 구분하면 된다.
3. 기본 엔티티 코드 한 번에 보기
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
protected User() {
}
public User(String email, String password) {
this.email = email;
this.password = password;
}
}
이제 하나씩 뜯어보자.
4. @Entity - “이 클래스는 JPA가 관리”
@Entity
public class User { }
- 이 클래스는 엔티티라고 JPA에 알려주는 애너테이션
- JPA는 이 클래스를 보고:
- 테이블 매핑
- SQL 생성
- 영속성 컨텍스트 관리
- 를 수행한다.
테이블 이름은?
- @Table을 안 쓰면 기본적으로 클래스명 기준으로 테이블 매핑
5. @Id - 식별자(PK)
@Id
private Long id;
- JPA가 엔티티를 구분하는 기준
- DB의 Primary Key
- 엔티티는 반드시 @Id가 하나 있어야 한다
JPA 입장에서: 이 객체가 이전에 저장된 건지, 새 객체인지”를 판단하는 기준이 바로 @Id다.
6. @GeneratedValue - PK 생성 전략
@GeneratedValue(strategy = GenerationType.IDENTITY)
- PK 값을 누가, 어떻게 만들지 정하는 설정
자주 쓰는 전략
- IDENTITY(MySQL, PostgreSQL에서 흔함)
- → DB가 AUTO_INCREMENT 같은 방식으로 생성
- AUTO
- → JPA가 DB에 맞는 전략을 자동 선택
👉 지금 단계에서는 “ID는 DB가 만들어준다” 정도로 이해하면 충분하다.
7. 기본 생성자가 왜 필요할까?
protected User() {
}
이건 JPA 필수 조건이다.
이유
- JPA는 엔티티를 조회할 때
- 리플렉션으로 객체를 생성한다
- 이때 기본 생성자가 반드시 필요
그래서:
- 기본 생성자 ❌ → JPA 동작 불가
- 기본 생성자 ⭕ → 정상 동작
8. 그런데 왜 protected인가?
여기서 중요한 의도가 하나 있다.
public이면?
public User() {}
- 아무나 new User() 가능
- 의미 없는 빈 엔티티 생성 가능
protected로 두면?
protected User() {}
- JPA는 사용 가능
- 외부 코드에서는 직접 생성 불가
- 엔티티 생성 규칙을 강제할 수 있음
👉 의도: 엔티티는 아무렇게나 만들지 말고, 의미 있는 생성자를 통해서만 만들게 하자.
9. 엔티티는 “무상태 객체”가 아니다
여기서 중요한 개념 하나 짚고 가자.
- 엔티티는 싱글톤 빈이 아니다
- 요청마다 새로 만들어질 수 있다
- 상태를 가진다
- 필드 값 변경
- 비즈니스 상태 표현
즉,
- Controller / Service → 무상태(stateless)
- Entity → 상태를 가진 도메인 객체
그래서 엔티티에는:
- 상태 변경 메서드
- 도메인 규칙
- 을 둘 수 있다.
10. 지금 단계에서 지켜야 할 엔티티 설계 규칙
- 엔티티에는 @Entity + @Id 필수
- 기본 생성자는 protected
- DTO와 엔티티는 분리
- 엔티티는 DB 구조를 반영
- 요청/응답 객체를 엔티티로 직접 쓰지 않는다
'백엔드' 카테고리의 다른 글
| [스프링 로드맵] D-1. Validation 기본 - DTO 검증이 필요한 이유 (0) | 2026.01.20 |
|---|---|
| [스프링 로드맵] C-3. Repository 실전 - JpaRepository가 해주는 것들 (1) | 2026.01.19 |
| [스프링 로드맵] C-1. JPA 큰 그림 - JPA vs Hibernate vs Spring Data JPA (0) | 2026.01.19 |
| [스프링 로드맵] B-3. DI/Bean 실전 - @Autowired, @Qualifier, Profile (0) | 2026.01.19 |
| [스프링 로드맵] B-2. DI/Bean 내부 - 빈 등록 방식과 라이프사이클 (1) | 2026.01.19 |