
application-dev.yml - open-in-view 설정 변경
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true
default_batch_fetch_size: 10 # 한번에 들고오는 개수 설정
defer-datasource-initialization: true
open-in-view: false # OSIV 개념 확인
REST API - 회원가입 만들기
진행 순서
- 응답 결과 확인하기
- 공통 DTO 사용해서 데이터 내려주기 설계
- 서비스 레이어 코드 수정 (레포지토리 코드 확인)
- 컨트롤러 레이어 코드 수정
JSON 응답 결과 값 샘플 먼저 보여 주기
{
"status": 200,
"msg": "성공",
"body": {
"id": 5,
"username": "tenco2",
"email": "a@naver.com"
}
}
package com.tenco.blog_v3.user;
import lombok.Getter;
import lombok.Setter;
public class UserResponse {
@Getter
@Setter
public static class DTO {
private int id;
private String username;
private String email;
//ex) User 엔티티 반환 --> 서비스 계층 DTO 객체로 변환 처리
public DTO(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.email = user.getEmail();
}
// 이메일 정보 포함을 안하고 싶다면
public DTO(User user, boolean includeEmail) {
this.id = user.getId();
this.username = user.getUsername();
this.email = includeEmail ? user.getEmail() : null;
}
}
}
UserService
/**
* 회원 가입 서비스
*/
@Transactional
public UserResponse.DTO signUp(UserRequest.JoinDTO reqDto ) {
// 1. username <-- 유니크 확인
Optional<User> userOp = userJPARepository.findByUsername(reqDto.getUsername());
if(userOp.isPresent()) {
throw new Exception400("중복된 유저네임입니다");
}
// 회원 가입 처리
User savedUser = userJPARepository.save(reqDto.toEntity());
System.out.println("savedUser : " + savedUser);
// c -> DTO 반환 처리
return new UserResponse.DTO(savedUser);
}
UserController
package com.tenco.blog_v3.user;
// ... 생략
@RequiredArgsConstructor
@Slf4j
@RestController // 코드 수정
public class UserController {
// @ResponseBody // 데이터 반환
@PostMapping("/join")
public ResponseEntity<ApiUtil<UserResponse.DTO>> join(UserRequest.JoinDTO reqDTO) {
// 회원가입 서비스는 --> 서비스 객체에게 위임한다.
UserResponse.DTO resDTO = userService.signUp(reqDTO);
return ResponseEntity.ok(new ApiUtil<>(resDTO));
}
// .. 생략
}
포스트 맨 확인

open-in-view: true란?
- open-in-view: true 설정은 Lazy Loading을 지원하기 위해 기본적으로 활성화되어 있는 설정입니다.
- 즉시로딩과 지연로딩을 관리하기 위해 트랜잭션이 끝난 후에도 영속성 컨텍스트를 유지하여 뷰 레이어까지 사용할 수 있도록 합니다. 이는 데이터베이스 연결을 길게 유지하기 때문에 간편하지만, 대규모 트래픽 상황에서는 성능 저하와 자원 낭비를 초래할 수 있습니다.
- REST API 설계에서는 권장되지 않습니다. API의 응답은 뷰와 무관하게 서비스 계층에서 필요한 데이터를 명시적으로 로딩하고 반환해야 하므로 open-in-view 설정을 false로 변경하여 트랜잭션을 명확히 관리하는 것이 좋습니다.


DTO(Data Transfer Object)를 사용하는 이유
문제점
- 커넥션 시간이 길어진다: 서비스에서 직접 Entity를 다룰 경우, 불필요한 필드까지 응답하게 되면서 데이터 전송 시간이 늘어나게 됩니다.
- 불필요한 필드 응답: Entity에는 민감한 정보나 사용되지 않는 필드가 포함될 수 있어, 응답에서 필요 없는 데이터까지 포함하게 됩니다.
- Lazy Loading 문제: MessageConverter가 JSON을 만들 때 Lazy Loading된 필드를 기다리지 않고 바로 JSON을 생성하려다 오류가 발생할 수 있습니다 (레이지 로딩된 부분을 호출하면 된다)
해결법
- open-in-view: false 설정: Lazy Loading을 사용하지 않고 필요 시점에 데이터 로딩을 처리합니다.
- Service 레이어 종료 전에 Lazy Loading 수행: 서비스에서 필요한 데이터를 명시적으로 모두 로딩하여 이후 단계에서 문제가 없도록 합니다.
- DTO 사용: Service에서 Entity 대신 DTO를 생성하여 클라이언트에 필요한 데이터만 응답합니다.
'Spring boot > 개념 공부' 카테고리의 다른 글
JwtUtil 만들어 보기 (0) | 2024.11.08 |
---|---|
JWT란 뭘까? (0) | 2024.11.08 |
공통 응답 DTO 및 예외 처리 구조 만들기 (0) | 2024.11.08 |
RestAPI 주소 변경 및 인터셉터 수정 (0) | 2024.11.08 |
뷰 연결 컨트롤러 정리 (0) | 2024.11.08 |

application-dev.yml - open-in-view 설정 변경
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true
default_batch_fetch_size: 10 # 한번에 들고오는 개수 설정
defer-datasource-initialization: true
open-in-view: false # OSIV 개념 확인
REST API - 회원가입 만들기
진행 순서
- 응답 결과 확인하기
- 공통 DTO 사용해서 데이터 내려주기 설계
- 서비스 레이어 코드 수정 (레포지토리 코드 확인)
- 컨트롤러 레이어 코드 수정
JSON 응답 결과 값 샘플 먼저 보여 주기
{
"status": 200,
"msg": "성공",
"body": {
"id": 5,
"username": "tenco2",
"email": "a@naver.com"
}
}
package com.tenco.blog_v3.user;
import lombok.Getter;
import lombok.Setter;
public class UserResponse {
@Getter
@Setter
public static class DTO {
private int id;
private String username;
private String email;
//ex) User 엔티티 반환 --> 서비스 계층 DTO 객체로 변환 처리
public DTO(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.email = user.getEmail();
}
// 이메일 정보 포함을 안하고 싶다면
public DTO(User user, boolean includeEmail) {
this.id = user.getId();
this.username = user.getUsername();
this.email = includeEmail ? user.getEmail() : null;
}
}
}
UserService
/**
* 회원 가입 서비스
*/
@Transactional
public UserResponse.DTO signUp(UserRequest.JoinDTO reqDto ) {
// 1. username <-- 유니크 확인
Optional<User> userOp = userJPARepository.findByUsername(reqDto.getUsername());
if(userOp.isPresent()) {
throw new Exception400("중복된 유저네임입니다");
}
// 회원 가입 처리
User savedUser = userJPARepository.save(reqDto.toEntity());
System.out.println("savedUser : " + savedUser);
// c -> DTO 반환 처리
return new UserResponse.DTO(savedUser);
}
UserController
package com.tenco.blog_v3.user;
// ... 생략
@RequiredArgsConstructor
@Slf4j
@RestController // 코드 수정
public class UserController {
// @ResponseBody // 데이터 반환
@PostMapping("/join")
public ResponseEntity<ApiUtil<UserResponse.DTO>> join(UserRequest.JoinDTO reqDTO) {
// 회원가입 서비스는 --> 서비스 객체에게 위임한다.
UserResponse.DTO resDTO = userService.signUp(reqDTO);
return ResponseEntity.ok(new ApiUtil<>(resDTO));
}
// .. 생략
}
포스트 맨 확인

open-in-view: true란?
- open-in-view: true 설정은 Lazy Loading을 지원하기 위해 기본적으로 활성화되어 있는 설정입니다.
- 즉시로딩과 지연로딩을 관리하기 위해 트랜잭션이 끝난 후에도 영속성 컨텍스트를 유지하여 뷰 레이어까지 사용할 수 있도록 합니다. 이는 데이터베이스 연결을 길게 유지하기 때문에 간편하지만, 대규모 트래픽 상황에서는 성능 저하와 자원 낭비를 초래할 수 있습니다.
- REST API 설계에서는 권장되지 않습니다. API의 응답은 뷰와 무관하게 서비스 계층에서 필요한 데이터를 명시적으로 로딩하고 반환해야 하므로 open-in-view 설정을 false로 변경하여 트랜잭션을 명확히 관리하는 것이 좋습니다.


DTO(Data Transfer Object)를 사용하는 이유
문제점
- 커넥션 시간이 길어진다: 서비스에서 직접 Entity를 다룰 경우, 불필요한 필드까지 응답하게 되면서 데이터 전송 시간이 늘어나게 됩니다.
- 불필요한 필드 응답: Entity에는 민감한 정보나 사용되지 않는 필드가 포함될 수 있어, 응답에서 필요 없는 데이터까지 포함하게 됩니다.
- Lazy Loading 문제: MessageConverter가 JSON을 만들 때 Lazy Loading된 필드를 기다리지 않고 바로 JSON을 생성하려다 오류가 발생할 수 있습니다 (레이지 로딩된 부분을 호출하면 된다)
해결법
- open-in-view: false 설정: Lazy Loading을 사용하지 않고 필요 시점에 데이터 로딩을 처리합니다.
- Service 레이어 종료 전에 Lazy Loading 수행: 서비스에서 필요한 데이터를 명시적으로 모두 로딩하여 이후 단계에서 문제가 없도록 합니다.
- DTO 사용: Service에서 Entity 대신 DTO를 생성하여 클라이언트에 필요한 데이터만 응답합니다.
'Spring boot > 개념 공부' 카테고리의 다른 글
JwtUtil 만들어 보기 (0) | 2024.11.08 |
---|---|
JWT란 뭘까? (0) | 2024.11.08 |
공통 응답 DTO 및 예외 처리 구조 만들기 (0) | 2024.11.08 |
RestAPI 주소 변경 및 인터셉터 수정 (0) | 2024.11.08 |
뷰 연결 컨트롤러 정리 (0) | 2024.11.08 |