[Project] 2차 프로젝트 - Error: Response 응답 데이터 관련

토글을 열어주세요 : )
김호정's avatar
Oct 25, 2024
[Project] 2차 프로젝트 - Error: Response 응답 데이터 관련
Response 응답 데이터 관련 - 해결완료
Admin 로그인 후 발급받은 JWT 토큰으로 전체 회원 리스트 조회 시
notion image
 

관리자 로그인 및 토큰 발급

notion image
notion image
 

발급받은 토큰으로 유저 목록 조회

notion image
// Lazy 로딩 사용 시 발생하는 에러 {"reason": Could not write JSON: failed to lazily initialize a collection of role: green.mtcoding.bookbox.user.User.lends: could not initialize proxy - no Session}
 

원인

  • lends 컬렉션을 직렬화할 때 Hibernate 세션이 닫힌 상태에서 접근하려고 하여 발생한 것..?
  • 컨트롤러가 데이터를 직렬화하여 JSON 반환 시점에 이미 Hibernate 세션이 종료됨. → lends 컬렉션 접근 시 No Session 오류 발생

해결1

  • User Entity에서 @OneToMany → Eager Fetching으로 변경
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER) private List<Lend> lends = new ArrayList<>();
→ 이 방법은 User Entity 조회 시 lends 컬렉션도 즉시 로딩됨. 하지만 Eager Loading은 성능에 영향을 미쳐서 필요한 경우에만 사용

해결2

  • 명시적 초기화를 통해 Lazy Loading 처리
public List<User> getUserList() { List<User> users = userRepository.findAll(); users.forEach(user -> Hibernate.initialize(user.getLends())); // Lazy 로딩 명시적 초기화 return users; }
 
 

해결3

  • UserDTO 생성
@Data public static class UserDTO { private Long id; private String username; private String email; private String phone; // 매개변수로 받음 public UserDTO(User user) { this.id = user.getId(); this.username = user.getUsername(); this.email = user.getEmail(); this.phone = user.getPhone(); } }
  • AdminService에서 DTO 변환
@Transactional public List<UserRequest.UserDTO> getUserList() { List<User> users = userRepository.findAll(); return users.stream() .map(UserRequest.UserDTO::new) // .collect(Collectors.toList()); }
 

Stream API

  • List 같은 컬렉션에서 데이터를 처리할 때 반복문 대신 사용
return users.stream() .map(UserRequest.UserDTO::new) // 각 User 객체를 UserDTO로 변환 .collect(Collectors.toList()); // 변환된 UserDTO들을 다시 List로 수집

users.stream():

  • usersList<User> 형식의 컬렉션
  • stream()은 이 리스트를 Stream 객체로 변환. Stream은 데이터를 일종의 "흐름"으로 다룰 수 있게 해줌
  • Stream API는 데이터를 처리하는 다양한 기능(필터링, 매핑, 정렬 등)을 제공

2. map(UserRequest.UserDTO::new):

  • map()은 Stream 내의 각 요소를 다른 타입으로 변환하는 역할
  • 여기서 UserRequest.UserDTO::new = User 객체를 UserDTO로 변환. → new UserRequest.UserDTO(user)와 같은 의미
  • 즉, 각각의 User 객체를 UserDTO 변환하여 새로운 스트림 생성

3. collect(Collectors.toList()):

  • collect()는 변환된 스트림 데이터를 최종적으로 리스트 형태로 수집하는 메소드
  • Collectors.toList()는 변환된 UserDTO 객체들을 다시 리스트로 모아서 반환
    • notion image
 
 
Share article

keepgoing