1. Entity
핵심 개념
- DB 테이블과 매핑되는 객체
- JPA 기준 @Entity
- 영속성 컨텍스트에 의해 관리됨
영속성 컨텍스트란?
엔티티를 저장하고 관리하는 JPA의 메모리 공간이다.
같은 트랜잭션 안에서 엔티티를 조회하면 동일 객체를 보장하고,
변경 감지(Dirty Checking)를 통해 자동으로 UPDATE 쿼리를 생성한다.
역할
- 데이터 저장
- 상태 변경
- 도메인 규칙 일부 포함 가능
- 연관관계 관리
Entity는 단순 데이터 구조가 아니라
도메인 모델의 중심 객체다.
예시
@Entity
public class User {
@Id
private Long id;
private String email;
private String password;
private String role;
}
이 구조는 DB 테이블과 1:1로 매핑된다.
즉, Entity는 DB 구조 그 자체에 가깝다.
2. DTO
핵심 개념
- 데이터를 전달하기 위한 객체
- 계층 간 전달용 객체
- API 요청/응답 전용 객체
DTO는 영속성과 무관하며,
DB와 직접적인 관계가 없다.
역할
- 필요한 데이터만 전달
- 응답 구조 설계
- 외부와의 계약 역할
- 내부 모델 보호
예시
public class UserResponseDto {
private String email;
private String role;
}
DTO는 API 응답 구조를 표현한다.
DB 구조와 동일할 필요가 없다.
3. Entity를 바로 반환하면 안 되는 이유
1) 보안 문제
Entity에는 내부 정보가 포함되어 있다.
예시:
- password
- 토큰
- 내부 관리 컬럼
- 삭제 여부
- 권한 정보
Entity를 그대로 반환하면 다음과 같은 응답이 나갈 수 있다.
{
"email": "...",
"password": "암호화된값",
"role": "ADMIN"
}
이는 심각한 보안 문제를 발생시킨다.
DTO를 사용하면 필요한 필드만 선택적으로 노출할 수 있다.
2) API 구조 = DB 구조가 되어버림
Entity를 그대로 반환하면
- DB 컬럼 변경
- 테이블 구조 변경
이 곧 API 스펙 변경으로 이어진다.
즉,
DB 변경 = 프론트 코드 수정
이 구조는 계층 분리를 깨뜨리고
API와 DB를 강하게 결합시킨다.
DTO를 사용하면 API 응답 구조를 독립적으로 유지할 수 있다.
3) 지연 로딩(Lazy Loading) 문제
예시:
@ManyToOne(fetch = LAZY)
private Store store;
Entity를 그대로 반환하면
Jackson 직렬화 과정에서 Lazy 로딩이 강제로 실행된다.
결과:
- 불필요한 추가 쿼리 발생
- N+1 문제
- 성능 저하
DTO로 필요한 데이터만 조회하면
지연 로딩 문제를 통제할 수 있다.
4) 양방향 연관관계 무한 루프
예시:
- User → Orders
- Orders → User
JSON 변환 시
User → Order → User → Order → ...
이 구조는 StackOverflowError를 발생시킬 수 있다.
DTO로 변환하면 필요한 방향만 잘라낼 수 있다.
5) 비즈니스 모델 노출
Entity는 내부 정책과 도메인 설계를 담고 있다.
- 상태 값
- 내부 로직
- 연관관계 구조
이를 그대로 외부에 노출하면
- 설계 의도가 드러난다.
- 내부 변경이 외부에 영향을 준다.
- 도메인 보호가 깨진다.
Entity는 내부 모델이고,
DTO는 외부 계약이다.
4. 올바른 구조 흐름
Controller
↓
Service
↓
Repository
↓
Entity
↓ (변환)
DTO
↓
Controller 응답
Service에서 Entity를 조회한 후
DTO로 변환하여 Controller에 반환한다.
Controller는 DTO를 그대로 응답한다.
이 구조가 가장 안전하고 유지보수에 유리하다.
최종 정리
Entity는 DB와 매핑되는 도메인 객체이며,
DTO는 계층 간 데이터 전달 및 API 응답을 위한 객체다.
Entity를 직접 반환하면
- 보안 노출
- API-DB 결합도 증가
- Lazy 로딩 문제
- 무한 참조 오류
- 도메인 모델 노출
등의 문제가 발생한다.
따라서 Entity는 내부 모델로 유지하고, 외부와의 통신은 반드시 DTO로 분리해야 한다.
정리하면, Entity는 내부 모델이고, DTO는 외부 계약이다.
'백엔드 기초 재정비 > 스프링 계층 구조 이해' 카테고리의 다른 글
| 트랜잭션 실패 사례와 롤백 필요성 정리 (0) | 2026.03.03 |
|---|---|
| 트랜잭션(Transaction) 개념과 주문 생성 예제 (0) | 2026.03.02 |
| 로그인 API가 하는 일과 요청 → 응답 흐름 정리 (0) | 2026.02.27 |
| Controller / Service / Repository 역할 정리 (0) | 2026.02.25 |