session은 JPA 영속성 컨텍스트가 유지되는 하나의 세션(트랜잭셔널 시작부터 종료)이다.
영속성 컨텍스트가 끝난 후에 연관된 엔티티를 조회할 때 문제가 발생한다.
나 같은 경우에는
@Data
@Builder
@AllArgsConstructor
public class UserInfoResponseDto {
private Long id;
private String name;
private String email;
private String univName;
private String major;
private Part part;
private Long ordinal;
private Role role;
public static UserInfoResponseDto of(User user){
return new UserInfoResponseDtoBuilder()
.id(user.getId())
.name(user.getProfile().getName())
.major(user.getUniversityInfo().getMajor())
.part(user.getProfile().getPart())
.ordinal(user.getUniversityInfo().getOrdinal())
.email(user.getAuthInfo().getEmail())
.univName(user.getUniversityInfo().getUniversity().getName())
.role(user.getAuthInfo().getRole())
.build();
}
}
이렇게 responseDto를 작성해주었는데, univName에서 해당 예외가 발생했다.
트랜잭셔널로 User를 조회할 때, User테이블만 조회해서 가져오고 Lazy로 매핑되어 있는 univName을 가져오려고 조회할 때 이미 영속성 컨텍스트가 종료된 시점이어서 예외가 발생한 것이다.
이를 해결하기 위해서 처음 User를 조회할 때, User 테이블만 조회하는 것이 아닌 university 테이블도 같이 조회해서 가져오면 해결 할 수 있다!
변경 전
User user = userRepository.findById(userId);
변경 후
User user = userRepository.findByIdWithUniversity(userId);
@Query(value = "SELECT u FROM User u join fetch u.universityInfo.university where u.id = :id ")
Optional<User> findByIdWithUniversity(Long id);
이와 같이 join fetch를 이용해서 university 엔티티까지 한번에 조회해서 가져왔다!