JPA 37

네이티브 쿼리

JPA가 SQL query를 그대로 사용하는 네이티브 쿼리를 지원한다. 하지만 가급적 네이티브 쿼리는 사용하지 않는게 좋다. 최근에 나온 final 방법 => 스프링 데이터 Projections 활용 스프링 데이터 JPA 기반 네이티브 쿼리 페이징 지원 반환 타입 Object[] Tuple DTO(스프링 데이터 인터페이스 Projections 지원) 제약이 있는데 Sort 파라미터를 통한 정렬이 정상 동작하지 않을 수 있고 JPQL처럼 Application loading 시점에 문법 확인이 불가하고 동적 쿼리가 불가능하다. // MemberRepository Interface @Query(value = "select * from member where username = ?", nativeQuery = ..

Projections

DB에서 엔티티를 조회하고 싶을 때도 있지만 회원의 이름만 조회하고 싶을때가 있다. JPA를 통해서 조회를 하게되면 엔티티를 통채로 조회하게 되면 쿼리의 데이터가 엄청 커지게 된다. 이름만 조회를 하고 싶을때 편하게 하는 방법을 Projections라고 한다. 쿼리에 SELECT절에 들어갈 데이터라고 보면 된다. UsernameOnly Interface를 만들고 package study.datajpa.repository; public interface UsernameOnly { String getUsername(); } MemberRepository Interface에 아래구문을 추가해준다. // 엔티티가 아니라 인터페이스 UsernameOnly에 구현체 프록시 객체가 담겨서 간다. List findPr..

새로운 엔티티를 구별하는 방법

새로운 엔티티를 판단하는 기본 전략 식별자가 객체일 때 `null`로 판단 식별자가 자바 기본 타입일 때 `0`으로 판단 `Persistable` 인터페이스를 구현해서 판단 로직 변경이 가능 Item Class를 하나 만들고 // Item Class package study.datajpa.entity; import lombok.Getter; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity @Getter public class Item { @Id @GeneratedValue private Long id; } ItemRepository Interface도 만들..

스프링 데이터 JPA 구현체 분석

스프링 데이터 JPA가 제공해는 공통 인터페이스의 구현체가 존재한다. 아래의 경로로 들어가보자 아래의 SimpleJpaRepository가 JPA의 구현체이다. 그리고 SimpleJpaRepository는 Repository가 이미 걸려있는데 두가지 의미가 있다. Spring Bean의 컴포넌트 스캔 대상이 되는 것 => 스프링이 읽어들여서 컨테이너에 올리게 되는 것이고 두번째는 JPA나 JDBC 둘 다 exception이 틀리기 때문에 이게 터지면 영속성 계층에 있는 것들을 Spring에서 쓸 수 있는 예외들로 다 바꿔준다. 서비스 계층이나 컨트롤러 계층에 있는 것들을 넘길 때 JPA exception이나 JDBC exception이 올라가는 것이 아니고 Spring Framework이 제공하는 exc..

Web 확장 - 도메인 클래스 컨버터 & 페이징과 정렬

path variable 기반으로 코드를 작성해보자. // MemberController Class package study.datajpa.controller; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import study.datajpa.entity.Member; import study.datajpa.repository.MemberRepository; ..

JPA Hint & Lock

JPA 쿼리 힌트 (SQL 힌트가 아니라 JPA 구현체에게 제공하는 힌트)이고 코드로 살펴보면 Hibernate는 readOnly라는 쿼리기능을 제공한다. JPA 영속성 컨텍스트에 딱 넣어놓고 (transaction commit 할때 자동으로 commit가 되는데 ) 강제로 flush를 하면 실제 db에 insert 쿼리가 나가고(영속성 컨텍스트에 member가 남아있는 상태로 => JPA 영속성 컨텍스트 안에 1차 캐시가 있는데 그걸 지우는 건 아니고 그것의 결과를 db에 동기화를 하는 것이고) clear를 하면 영속성 컨텍스트가 다 날라간다. 그 이후로 JPA에서 조회를 하면 영속성 컨텍스트에 1차캐시가 없기 때문에 db를 무조건 조회한다. // MemberRepositoryTest @Test pub..

@EntityGraph

JPA의 fetchjoin 기술(지연로딩개념 : LAZY)을 명확히 이해한 다음에 @EntityGraph로 넘어오자. 먼저 MemberRepositoryTest를 작성하면 member1은 teamA를 참조하고 member2는 teamB를 참조한다. @Test public void findMemberLazy() { //given //member1 -> teamA //member2 -> teamB Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); teamRepository.save(teamA); teamRepository.save(teamB); Member member1 = new Member("member1", 10, teamA); Membe..

공통 인터페이스 설정 & 적용

MemberRepository는 아래와 같고 testcase로 가보자. package study.datajpa.repository; import org.springframework.data.jpa.repository.JpaRepository; import study.datajpa.entity.Member; public interface MemberRepository extends JpaRepository { } MemberRepositoryTest에서 System.out.println("memberRepository = " + memberRepository.getClass()); 찍어보면 package study.datajpa.repository; import org.assertj.core.api.Ass..

실전 예제 1 - 요구사항 분석과 기본 매핑

아래 요구사항을 가지고 간단한 쇼핑몰 예제를 만들어 보자. 회원과 주문의 1대다 관계 주문과 주문상품의 관계 1대다 주문상품과 상품의 관계 다대일 테이블 설계와 엔티티 설계 매핑 그림은 아래와 같다. 엔티티 설계와 매핑 예시를 코드로 구현해보자. maven으로 새로운 프로젝트를 생성해준다. 폴더구조에서 persistence.xml을 만들어 주고 설정을 해준다. Member Order OrderItem Item Class를 각각 만들어준다. Member Class에서 Id 식별자는 필수로 해준다. getter setter을 만들어 준다.(setter는 많이 만들면 코드 추적하기가 어렵고 유지보수성에서 떨어진다.) package jpabook.jpashop.domain; import javax.persist..

Spring/JPA 2022.04.14