[Spring JPA] 스프링 애플리케이션의 JPA open-in-view 설정 (Feat. 지연로딩)

류넹·2024년 3월 22일
1

Spring

목록 보기
48/50

Spring 애플리케이션의 open-in-view 설정

spring.jpa.open_in_view 설정 : 커넥션을 언제 반납할지를 결정하는 설정

  • spring.jpa.open_in_view=true : 응답이 완료될 때 커넥션 반납
  • spring.jpa.open_in_view=false : 서비스의 메소드가 종료될 때 커넥션 반납
  • 기본값 : true
  • 기본값이 true이기 때문에 응답이 완료될 때까지 커넥션이 반납되지 않는다.
  • true로 설정하는 경우는 관리자 페이지와 같이 사용량이 많지 않은 경우, 지연로딩을 @Transactional 어노테이션이 부착된 곳을 벗어나 뷰 템플릿에서도 사용할 수 있다.
  • 단, 사용량이 많은 서비스인 경우에는 커넥션을 바로 반납하는 것이 좋기 때문에 false로 설정해야 한다.
  • false로 설정해서 사용할 때는 반드시 @Transactional 어노테이션이 부착된 메소드내부에서 (필요에 따라서) 지연로딩 관련 초기화를 전부 처리해야 한다.




❓ false로 설정하는 경우

Entity

@Entiy
public class Post {
	@Id
    Long id;
    
    String title;
    
    @OneToMany(fetch = FetchType.LAZY)
    Set<Voter> voters;
}

HTML - 화면 출력

<div th:text="${post.id}"></div>
<div th:text="${post.title}"></div>
<div th:text="${#sets.size(post.voters)}"></div>

Service

  • Post 엔티티를 획득해서 반환했다.
    • Voter 객체를 사용하지 않았다.
  • 오류 발생
    • connection이 끊겼기 때문에 HTML에서 ${#sets.size(post.voters)} 출력 불가
@Service
@RequiredArgsConstructor
public class PostService {
	private final PostRepository postRepository;
    
    public Post getPostDetail(Long id) {
		Post post = postRepository.findById(id);
        return post;
    }
}




📌 오류 극복하려면?

1. Dto 클래스 생성하기

public class PostDetailDto {
	Long id;
    String title;
    Set<Voter> voters = new HashSet<Voter>;
    
    public void addVoter(Voter voter) {
    	voters.add(voter);
    }
}

2. Service

PostDetailDto타입의 getPostDetail() 메소드 추가

  • Post 엔티티를 획득했다.
  • Post 엔티티의 id, title, voters의 Voter를 사용했다.
  • 지연로딩되었던 것이 조회됨
@Service
@RequiredArgsConstructor
public class PostService {
	private final PostRepository postRepository;
    
    public Post getPostDetail(Long id) {
		Post post = postRepository.findById(id);
        return post;
    }
    
    public PostDetailDto getPostDetail(Long id) {
    	Post post = postRepository.findById(id);
        
        PostDetailDto dto = new PostDetailDto();
        dto.setId(post.getId());
        dto.setTitle(post.getTitle());
        
        for (Voter voter : post.getVoters()) {
        	dto.addVoter(voter);
        }
        
        return dto;
    }
}

JPA를 사용할 경우, 이와 같이
Entity에 있는 데이터를 DTO에 담는 코드 작성이 매우 빈번함

참고 이미지)

profile
학습용 커스터마이징 간단 개발자 사전

0개의 댓글