본문 바로가기

JPA

(5)
[JPA] QueryDSL stream DB connection 에러 해결 과정 ① 버전 Spring Boot 2.7.4 QueryDSL 5.0.0 MySQL 5.7 DB 데이터를 가공해 카프카로 전송하는 애플리케이션을 만들면서 약 1주간 많은 난관에 봉착했고 많은 삽질을 했다. 어떤 에러가 있었고 어떻게 해결하였는지에 대해 공유하고자 한다. ① stream() 으로 레코드 한 건씩 가져오는 건 줄 알았는데 왜 타임아웃이 나지!? 결론 .fetch().stream() 는 Java의 스트림, .stream() 은 DB의 스트리밍 방식이다! 에러 현상 쿼리 호출 대상인 tableA 테이블은 몇 십 만건의 데이터를 가지고 있다. 그래서 데이터를 한꺼번에 들고 오면 타임아웃이 나거나 메모리가 터질 수 있으므로 스트리밍 방식을 적용해 한 건씩 처리하기 위해 다음과 같이 구현을 하였다. publi..
[JPA] Multi Datasource 설정하기 Spring Data Jpa 에서 한 개의 DB만 사용한다면 application.yml 만 설정해도 auto configuration 을 통해 자동으로 DB 커넥션이 생성된다. 하지만 한 프로젝트에 접근할 DB가 2개 이상이라면? 혹은 다른 DB 서버도 접근해야한다면? 귀찮지만 Configuration 클래스를 생성 해줘야한다. ※ 참고 single datasource 일때 application.yml 설정을 참고하면 좋을 듯하다. application.yml spring: datasource: url: jdbc:h2:tcp://localhost/~/member username: sa password: hikari: idle-timeout: 0 maximum-pool-size: 1 jpa: databa..
[JPA] Querydsl 시작하기 Querydsl 이란? JPQL 생성을 도와주는 라이브러리이다. Querydsl 메소드를 사용해 작성한 쿼리는 JPQL 로 변환되어 SQL 쿼리가 실행된다. 사용하는 이유 쿼리 메소드는 메소드명만으로 하이버네이트가 SQL로 변환해주기 때문에 간단하게 사용할 때는 너무나 강력하다. 하지만 join 을 쓰거나 쿼리가 복잡해지면 JPQL 로도 결국 SQL 쿼리 짜듯이 문자열로 작성하는 수 밖에 없다. 하지만 Querydsl 를 사용하면 여전히 메소드를 활용해 쿼리를 생성하는 것이 가능하다. @Query 애노테이션으로 JPQL을 짜면 syntax error를 애플리케이션 실행을 해봐야 알 수 있다. 하지만 Querydsl를 사용하면 메소드와 변수로 쿼리를 만들기 때문에 애초에 syntax error 나기가 힘들..
[JPA] Querydsl 에서 Fetch Join 적용 안되는 이유 문제 상황 Fetch join 은 한 번의 쿼리로 JOIN 대상 테이블 데이터까지 한 번에 가져오고 영속성 컨텍스트에 넣어주기 때문에 n+1 문제를 해결하기 위한 하나의 방법이다. 그래서 fetch join 을 적용하면 실제로 그렇게 되는지 확인해보고 싶었다. Querydsl QBook book = QBook.book; QPaper paper = QPaper.paper; List bookList = jpaQueryFactory .selectFrom(book) .join(book).on(book.id.eq(paper.id)).fetchJoin() .fetch(); 생성된 SQL SELECT book.id FROM book INNER JOIN paper ON (book.id=paper.id) SELECT p..
[JPA] 영속성 컨텍스트(Persistence Context) : 엔티티 관리 공간 영속성 컨텍스트(Persistence Context) 엔티티를 관리하는 논리적인 공간이다. DB 와의 동기화를 위해 엔티티 변경 정보를 관리한다. 엔티티를 등록, 해제할 수 있어 그 상태를 관리하는 엔티티 생명주기가 존재한다. 엔티티 생명 주기 em.persist(member); 를 하면 Member 객체가 영속성 컨텍스트에 등록되어 commit 시 CRATE 쿼리로 변환해 실행하여 DB와 동기화를 한다. persist() 호출 전인 객체(비영속) 나 detached(준영속)나 removed(삭제) 된 엔티티는 아무리 setter로 데이터를 변경하거나 무슨 짓을 해도 DB 에 반영되지 않는다. 영속성 컨텍스트는 그 사실을 모르기 때문이다. flush(): 영속성 컨텍스트와 DB 를 동기화하는 메소드 쓰기..