백엔드 기초 재정비/스프링 계층 구조 이해

DTO vs Entity 정리

namerong 2026. 2. 26. 21:32

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는 외부 계약이다.