Home > Troubleshooting > πŸ”[Troubleshooting] πŸš€ Java DTO 문제.

πŸ”[Troubleshooting] πŸš€ Java DTO 문제.
Troubleshooting Backend Development Spring Boot DTO SOLID

πŸš€ Java DTO Troubleshooting

πŸ“‹ λͺ©μ°¨

  1. 문제 상황
  2. ν•΄κ²° 방법
  3. @NoArgsConstructor μ΄ν•΄ν•˜κΈ°
  4. λ¦¬ν”Œλ ‰μ…˜μ˜ μ—­ν• 
  5. 싀무 적용 팁

🚨 문제 상황

DTO ν΄λž˜μŠ€μ—μ„œ final ν•„λ“œμ™€ @NoArgsConstructorλ₯Ό ν•¨κ»˜ μ‚¬μš©ν•  λ•Œ λ°œμƒν•˜λŠ” 컴파일 μ—λŸ¬

μ—λŸ¬ λ©”μ‹œμ§€: variable might not have been initialized


βœ… ν•΄κ²° 방법

Before (문제 μ½”λ“œ)

@Getter
@Setter
public class CategoryDto {
    private final Long id;        // ❌ final ν‚€μ›Œλ“œ 문제
    private final String name;    // ❌ final ν‚€μ›Œλ“œ 문제
    // ...
}

After (μˆ˜μ •λœ μ½”λ“œ)

@Getter
@Setter
@NoArgsConstructor  // βœ… κΈ°λ³Έ μƒμ„±μž μžλ™ 생성
public class CategoryDto {
    private Long id;        // βœ… final 제거
    private String name;    // βœ… final 제거
    // ...
}

πŸ” μˆ˜μ • 이유

DTOλŠ” 데이터 전솑 κ°μ²΄λ‘œμ„œ μ—¬λŸ¬ κ³„μΈ΅μ—μ„œ 값이 ν• λ‹Ήλ˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ finalλ³΄λ‹€λŠ” 일반 ν•„λ“œλ‘œ μ„ μ–Έν•˜λŠ” 것이 μΌλ°˜μ μž…λ‹ˆλ‹€.


πŸ”§ @NoArgsConstructor μ΄ν•΄ν•˜κΈ°

κΈ°λ³Έ κ°œλ…

@NoArgsConstructorλŠ” Lombok μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ, λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” κΈ°λ³Έ μƒμ„±μžλ₯Ό μžλ™μœΌλ‘œ μƒμ„±ν•©λ‹ˆλ‹€.

Lombok μ‚¬μš© μ „/ν›„ 비ꡐ

μˆ˜λ™ μž‘μ„± (Before)

public class CategoryDto {
    private Long id;
    private String name;

    // κ°œλ°œμžκ°€ 직접 μž‘μ„±ν•΄μ•Ό ν•˜λŠ” κΈ°λ³Έ μƒμ„±μž
    public CategoryDto() {
    }
    
    // getter, setter λ©”μ„œλ“œλ“€...
}

Lombok μ‚¬μš© (After)

import lombok.NoArgsConstructor;

@NoArgsConstructor  // κΈ°λ³Έ μƒμ„±μžλ₯Ό 컴파일 μ‹œμ μ— μžλ™ 생성
public class CategoryDto {
    private Long id;
    private String name;
    
    // public CategoryDto() {} κ°€ μžλ™μœΌλ‘œ 생성됨
}

🚫 final과의 좩돌 이유

  • final ν•„λ“œλŠ” μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™” λ˜λŠ” μƒμ„±μžμ—μ„œ μ΄ˆκΈ°ν™” ν•„μˆ˜
  • @NoArgsConstructorλŠ” λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” μƒμ„±μžλ₯Ό 생성
  • λ§€κ°œλ³€μˆ˜ μ—†λŠ” μƒμ„±μžμ—μ„œλŠ” final ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•  방법이 μ—†μŒ

πŸ” λ¦¬ν”Œλ ‰μ…˜μ˜ μ—­ν• 

λ¦¬ν”Œλ ‰μ…˜μ΄λž€?

ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰ 쀑(Runtime)에 자기 μžμ‹ μ„ 듀여닀보고 μ‘°μž‘ν•  수 있게 ν•΄μ£ΌλŠ” κΈ°λŠ₯

πŸ—οΈ Spring/JPAμ—μ„œμ˜ ν™œμš©

1. Spring DI (μ˜μ‘΄μ„± μ£Όμž…)

@Service
public class PostService {
    // Spring이 λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ Bean 생성
}

2. JPA μ—”ν‹°ν‹° 생성

@Entity
public class Post {
    // JPAκ°€ DB 쑰회 κ²°κ³Όλ₯Ό 객체둜 λ³€ν™˜ν•  λ•Œ κΈ°λ³Έ μƒμ„±μž μ‚¬μš©
}

3. JSON 역직렬화

@RestController
public class PostController {
    
    @PostMapping("/posts")
    public void createPost(@RequestBody PostSaveRequestDto dto) {
        // Jackson이 JSON β†’ DTO λ³€ν™˜ μ‹œ κΈ°λ³Έ μƒμ„±μž μ‚¬μš©
    }
}

πŸ”„ λ¦¬ν”Œλ ‰μ…˜ λ™μž‘ κ³Όμ •

  1. 객체 생성: κΈ°λ³Έ μƒμ„±μžλ‘œ 빈 객체 생성
  2. ν•„λ“œ 탐색: λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ 클래슀의 ν•„λ“œ 정보 μˆ˜μ§‘
  3. κ°’ μ£Όμž…: 각 ν•„λ“œμ— 데이터 ν• λ‹Ή

⚠️ λ¦¬ν”Œλ ‰μ…˜μ˜ 단점

단점 μ„€λͺ…
μ„±λŠ₯ μ €ν•˜ 일반적인 λ©”μ„œλ“œ ν˜ΈμΆœλ³΄λ‹€ 느림
μΊ‘μŠν™” μ €ν•΄ private ν•„λ“œμ—λ„ μ ‘κ·Ό κ°€λŠ₯
컴파일 μ‹œμ  체크 λΆˆκ°€ μ‹€ν–‰ μ „κΉŒμ§€ 문제 발견 어렀움

πŸ’‘ 싀무 적용 팁

1. DTO 섀계 κ°€μ΄λ“œλΌμΈ

// βœ… ꢌμž₯ν•˜λŠ” DTO ꡬ쑰
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor  // λͺ¨λ“  ν•„λ“œλ₯Ό λ°›λŠ” μƒμ„±μžλ„ ν•¨κ»˜ 제곡
public class UserDto {
    private Long id;
    private String username;
    private String email;
    private LocalDateTime createdAt;
}

2. μ—”ν‹°ν‹° vs DTO ꡬ뢄

ꡬ뢄 Entity DTO
λͺ©μ  DB ν…Œμ΄λΈ” λ§€ν•‘ 데이터 전솑
final μ‚¬μš© κ°€λŠ₯ (ID λ“±) μ§€μ–‘
μƒμ„±μž @NoArgsConstructor ν•„μˆ˜ @NoArgsConstructor ꢌμž₯

3. Lombok μ–΄λ…Έν…Œμ΄μ…˜ μ‘°ν•©

// μ‹€λ¬΄μ—μ„œ 자주 μ‚¬μš©ν•˜λŠ” μ‘°ν•©
@Data  // @Getter + @Setter + @ToString + @EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Builder  // λΉŒλ” νŒ¨ν„΄ 지원
public class ProductDto {
    private Long id;
    private String name;
    private BigDecimal price;
}

4. 검증 μ–΄λ…Έν…Œμ΄μ…˜κ³Ό ν•¨κ»˜ μ‚¬μš©

@Getter
@Setter
@NoArgsConstructor
public class CreateUserRequestDto {
    
    @NotBlank(message = "μ‚¬μš©μžλͺ…은 ν•„μˆ˜μž…λ‹ˆλ‹€")
    private String username;
    
    @Email(message = "μ˜¬λ°”λ₯Έ 이메일 ν˜•μ‹μ΄ μ•„λ‹™λ‹ˆλ‹€")
    private String email;
    
    @Size(min = 8, message = "λΉ„λ°€λ²ˆν˜ΈλŠ” μ΅œμ†Œ 8자 이상이어야 ν•©λ‹ˆλ‹€")
    private String password;
}

πŸ“ μš”μ•½

  1. DTOμ—μ„œλŠ” final ν‚€μ›Œλ“œ μ§€μ–‘ - 데이터 전솑 νŠΉμ„±μƒ κ°’ 변경이 ν•„μš”
  2. @NoArgsConstructor ν•„μˆ˜ - Spring/JPA의 λ¦¬ν”Œλ ‰μ…˜ 기반 λ™μž‘μ„ μœ„ν•΄
  3. λ¦¬ν”Œλ ‰μ…˜ 이해 - ν”„λ ˆμž„μ›Œν¬κ°€ λ™μ μœΌλ‘œ 객체λ₯Ό μƒμ„±ν•˜κ³  μ‘°μž‘ν•˜λŠ” 원리
  4. 싀무 팁 ν™œμš© - Lombok μ‘°ν•©κ³Ό 검증 μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ 효율적인 DTO 섀계