본문 바로가기

Back-End/JPA21

querydsl 단 건 조회시 firstResult/maxResults specified with collection fetch; applying in memory! Querydsl private Member getMember(Long memberId) { return jpaQueryFactory .selectFrom(member).distinct() .leftJoin(member.groupMember, groupMember).fetchJoin() .leftJoin(groupMember.group, group).fetchJoin() .where(member.id.eq(memberId)) .fetchFirst(); } Member Entity의 코드이다. // Member.class @Column(name = "email", nullable = false, unique = true) private String email; @Column(name = "name", nul.. 2022. 9. 2.
JPA 연관관계 양방향 매핑 Entity 조회시 문제&해결 사실 제목은 마음에 들지 않는다. N+1 문제라고 예상할 수 있겠지만, N+1 쿼리에 의한 문제에 대한 포스팅은 아니다. 새 프로젝트를 해보면서 여러가지 Query를 실행해보면서 경험을 쌓기위해서 하고 있었다. 문제 상황 및 예상결과 1. 한개의 Todo Entity에 6개의 Comment Entity가 달려있다. 2. QueryDSL을 통해서 조회를 한다 3. Log에는 1개의 Todo Entity와 그 객체안에 Comment Entity가 List 타입으로 저장되어 출력된다. Todo Class @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "TODO_ID") private Long id; @Column(nullable .. 2022. 4. 28.
JPA) deleteById 호출 시 연관객체 SQL 줄이기 Todo.class (부모 클래스) @Entity public class Todo extends DateEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "TODO_ID") private Long id; @Column(nullable = false) // text private String content; // 내용 @Column(name = "MEMBER_ID", nullable = false) private String writer; // 작성자 -> Member @Convert(converter = TodoCheckedConverter.class) private boolean checked; @OneToMa.. 2022. 4. 1.
JPA) 벌크 연산 Entity 를 수정하려면 영속성 컨텍스트의 변경 감지 기능이나 병합을 사용하고, 삭제하려면 EntityManager.remove() 를 사용한다. 하지만 이 방법으로 수 백개 이상의 Entity 를 하나씩 처리하기에는 시간이 너무 오래걸린다. 이럴 떄 여러 건을 한번에 수정하거나 삭제하는 벌크 연산을 쓰면 된다. String qlString = "update Product p set p.price = p.price * 1.1 where p.stockAmount < :stockAmount"; int resultCount = em.createQuery(qlString) .setParamter("stockAmoun", 10) .executeUpdate(); 벌크 연산은 executeUpdate() 메서드를 .. 2022. 3. 30.
JPA) Join Fetch, @EntityGraph 차이점 기본적으로 JPA를 사용하다보면 발생하는 대표적인 성능문제가 있다. 바로 N+1 문제이다. N+1 문제에 대한 해결책은 대체로 알려진 방식이 많이 있다. 간단하게 나열하면 다음과 같다. 1. Join Fetch 의 사용 2. @EntityGraph 이외에도 Batch Size 설정 & Hibernate Fetch Mode 설정 등이 있다. 사실 Join Fetch, @EntityGraph 라는 대답은 모두가 알고 있다. 대부분 JPA를 공부하는 개발자라면 알고있다. 두 설정의 공통점은 N+1을 해결한다는 점이지만, 해결하는 과정에서 조금의 차이가 존재한다. 그것은 사용하는 SQL이 다르다는 점이다. 연관관계의 fetch 속성은 LAZY 로 설정했다 1. @EntityGraph 를 사용 한 경우 @Enti.. 2022. 3. 24.
JPA) Spring OSIV 스프링 OSIV 스프링 에서 제공하는 OSIV 는 ‘비즈니스 계층에서 트랜잭션을 사용하는 OSIV’ 이다. 말 그대로 비즈니스 계층에서만 트랜잭션을 사용하는 것이다. 동작원리는 다음과 같다. 요청이 들어오면 서블릿필터 나 스프링 인터셉터 에서 영속성 컨텍스트를 생성한다. Service 계층에서 트랜잭션을 시작할 때 생성되어 있던 영속성 컨텍스트를 찾아서 트랜잭션을 실행한다. Service 계층 이 끝나면 트랜잭션을 커밋하고 Flush 한다. 이때 트랜잭션만 종료된다. Controller , View 까지 영속성 컨텍스트가 유지되므로 조회된 엔티티는 영속상태를 유지한다. 필터 나 인터셉터 로 요청이 돌아오면 영속성 컨텍스트를 종료한다, 이때 Flush 는 일어나지 않는다. 트랜잭션 없이 읽기 영속성 컨텍스.. 2022. 3. 14.