본문 바로가기

Spring/JPA

(30)
JPA- Open Session In View OSIV 기본적으로 스프링 프로젝트를 실행하면, warn 로그가 뜨면서 spring.jpa.open-in-view : true 기본값이라고 알려준다. 기본적으로 OSIV 전략은 최초 데이터베이스 커넥션 시작 시점부터 View, API 응답이 끝날 때까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다. @PostMapping("/api/v1/members") public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) { Long id = memberService.join(member); return new CreateMemberResponse(id); } @Transactional public Long join(Member me..
JPA- DISTINCT DISTINCT join fetch로 컬렉션을 조인하여 조회하는 경우 동일 엔티티가 중복 조회되는 문제가 존재한다. 예를 들어 Team1이라는 엔티티에 Member엔티티 3개(member1, member2, member3)가 매핑 되어있다고 하자. 이때 " select t from Team t join fetch t.members where t.name = "TEAM1" "라는 jpql로 쿼리를 날리게 된다면 이는 sql로 " SELECT T.*, M.* FROM TEAM T JOIN MEMBER M ON T.MEMBER_ID = M.MEMBER_ID WHERE T.NAME = "TEAM1" "로 번역되어 조인된 테이블은 총 세개 row가 만들어질 것이다. 여기서 distinct 키워드를 추가하여 "se..
JPA- 벌크연산 JpqlMain.class package jpql; public class JpqlMain { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try { // 멤버 100명 persist for (int i = 0; i < 100; i++) { Member member = new Membe..
JPA-Join Fetch 패치 조인 jpql select m from Member m join fetch m.team sql SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID = T.ID join fetch를 하면 원래 가져오려는 테이블과 패치 조인한 테이블을 조인한 테이블을 생성하고, 그 테이블을 가져온다. 예를 들어 DB에 Team 엔티티가 하나 저장되어 있고, Team에는 두개의 Member 엔티티가 컬렉션 형태로 연관되어 있다고 하자. (Team:Member = 일대다) "select t from Team t join fetch t.members"로 Team 엔티티와 연관된 Member 컬렉션을 가져오려고 할 때, Team에 연관된 Member가 두개라서 총 두개..
JPA- 경로 표현식 경로 표현식 상태필드 상태필드는 단순히 값을 저장하기 위한 필드로 엔티티의 내부 멤버 변수라고 생각하면 된다. ex) m.username 연관 필드 연관 필드는 연관관계를 위한 필드이다. - 단일 값 연관 필드 만일 Member 엔티티에 ManyToOne으로 연관된 Team 엔티티가 있다고 하면 이때 m.team은 단일값 연관 필드가 된다. 단일 값 연관 경로는 묵시적 내부 조인이 발생한다. 단순히 말해서 자동으로 TEAM 테이블의 내용이 MEMBER 테이블을 조회할 때 자동으로 조인된다. String query = "select m.team From Member m"; List result = em.createQuery(query, Team.class).getResultList(); 쿼리 출력>>> /..
JPA- 조건식의 사용 CASE 문 일반적으로 case문을 통해서 어떠한 결과를 가져올지 구분을 한다. jpql도 case 문을 지원하기에 다음과 같이 사용이 가능하다. package jpql; public class JpqlMain { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try { Member me..
JPA-타입 표현 jpql에서 enum의 경우 표현하려면 "패키지.enum 클래스.enum 타입"으로 표현해야 한다. Member.class package jpql; import lombok.Getter; import lombok.Setter; import javax.persistence.*; @Entity @Getter @Setter public class Member { @Id @GeneratedValue private Long id; private String username; private int age; @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "TEAM_ID") private Team team; private MemberType type; ... } ..
JPA- 조인 내부 조인 package jpql; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import java.util.List; public class JpqlMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager();..