728x90
반응형

Hibernate 21

[JPQL] JOIN 원하는 엔티티 여러개 가져오기

JPA 객체 참조특성으로 JOIN이 되더라도 연관관계로만 데이터를 못가져 오는 경우, JPQL에서 인위적으로 JOIN을 걸어야하는 상황이 발생할때가 있습니다. 기본적인 쿼리는 아래와 같습니다. SELECT project.*, user_project.*, project_part.* FROM project LEFT JOIN user_project ON (user_project.project_no = project.project_no) AND (user_project.user_no = 1) LEFT JOIN project_part ON (project_part.project_part_no = user_project.project_part_no); 3개의 테이블을 JOIN해서 데이터를 모두 가져오거나 원하는 데..

Hibernate/JPQL 2023.09.13

[JPA] EntityManager 기본 설정 및 개념 정의

EntityManager 기본설정 비영속상태 준영속상태 객체 영속화 트랜잭션 커밋 영속객체조회 쓰기지연 변경감지 플러쉬 EntityManager기본설정 [persistence.xml] EntityManagerFactory를 통해 등록한 Persistence Unit 이름을 지정해준다. public class JpaExampleMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabasic"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction()..

[JPA] UPDATE 변경감지와 병합 (DirtyChecking / Merge)

엔티티는 영속상태로 관리된다. 이렇게 영속상태에서 관리되는 엔터티의 값을 변경하게 되면 JPA는 Transaction Commit시점에 변경된 내용을 확인하고 Database에 반영한다. 이것을 '변경감지' 'DirtyChecking' 이라고 한다. 변경 감지(DirtyChecking) : Transaction commit시점에 엔티티의 변경을 감지해서 updateQuery를 날려준다. @SpringBootTest @Transactional public class ItemUpdateTest { @PersistenceContext EntityManager em; @Test @Rollback(false) public void updateTest() throws Exception { Book saveBook ..

[JPA] 영속성 전이와 고아객체 (CASCADE, orphaRemoval)

CASECADE ALL : 전체 적용 PERSIST : 영속 REMOVE : 삭제 MERGE : 병합 REFRESH : REFRESH DETACH : DETACH @Entity @Getter @Setter public class Parent { @Id @GeneratedValue @Column(name = "PARENT_ID") private Long id; private String name; @OneToMany(mappedBy = "parent") private List childList = new ArrayList(); /* 연관관계 편의 메소드 - childList에 값 추가, parent값 초기화 */ public void addChild(Child child) { childList.add(ch..

[JPA] 즉시로딩/지연로딩(Eager/Lazy) 과 JPQL N+1 이슈

지연로딩(Lazy) JPA는 지연로딩 전략을 지원한다. @ManyToOne(fetch = FetchType.LAZY) 위와 같이 @XxxTOXxx 어노테이션의 fetch옵션을 통해 로딩 전략을 설정할 수 있으며 Eager, Lazy 두개의 전략을 설정할 수 있다. Eager : 즉시로딩 연관관계 엔티티를 모두 조회한다. @ManyToXxxx fetch 옵션 기본값이다 Lazy : 지연로딩 현재 조회하려는 엔티티만을 조회하고, 연관관계 엔터티는 객체탐색으로 탐색하는 순간 조회된다. @XxxxToMany fetch 옵션 기본값이다 [User Entity] @Entity(name = "USERS") @Setter @Getter @ToString public class User { @Id @GeneratedVa..

[JPA] JPA에서 Proxy 객체란?

프록시 find() : 데이터베이스를 통해서 실제 엔티티 객체를 조회한다. getReference() : 데이터베이스 조회를 미루는 Proxy(가짜) 엔티티 객체를 조회한다. 위와같이 JPA에서는 em.find 뿐만 아니라 em.getReference()라는 메서드도 지원해준다. 아래 테스트 코드를 통해 find() 메소드로 User를 조회해 보자. [find() user 테스트코드] @SpringBootTest @Transactional @Commit class DemoApplicationTests { @PersistenceContext EntityManager em; @Test void Proxy() { User user = new User(); user.setUsername("hello"); em...

[JPA] 상속 관계 매핑 @Inheritance , @Discriminator____

관계형 데이터베이스는 상속관계가 없다 관계형 데이터베이스에는 슈퍼타입 서브타입 관계라는 모델링 기법이 있으며 이것이 객체 상속과 유사하다. 상속관계 매핑이란? 객체의 상속과 구조와 데이터베이스의 슈퍼타입 서브타입 관계를 매핑한다. 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법은 다음과 같다. 조인 전략 : 각각 테이블로 변환 단일 테이블 전략 : 통합 테이블로 변환 구현 클래스마다 테이블 전략 : 서브타입 테이블로 변환 1. 조인 전략 - 각각의 테이블로 변환 예를들어 앨범, 책, 영화 라는 상품이 있다고 가정하자. 상품을 아이템이라는 슈퍼 테이블을 설계하고 앨범, 영화, 책으로 분류하여 서브 테이블을 설계한 뒤 데이터를 같이 조회할 때 JOIN으로 검색한다. 공통 요소인 상품 이름, 상..

[JPA] 값 타입 컬렉션 (@ElementCollection / @CollectionTable)

컬렉션 값 타입이란 값 타입을 컬렉션에 담아 사용하는것을 말한다. 값 타입 하나 이상을 저장할 때 사용한다. 예를들어, 내가 좋아하는 책 , 혹은 주소 이력을 보관한다고 하면 별도의 테이블을 생성해서 데이터를 관리해야한다. 개념적으로 보면 1:M 관계가 형성된다. 데이터베이스 컬렉션을 같은 테이블에 저장할 수 없다, 따라서 컬렉션을 저장하기 위한 별도의 테이블이 필요하다. @ElementCollection 과 @CollectionTable 어노테이션을 사용한다. @ElementCollection @CollectionTable(name = "FAVORITE_BOOK", //매핑 정보(컬렉션의 테이블명) joinColumns = @JoinColumn(name = "USER_ID")) //USER_ID를 FK..

[JPA] 값 타입 객체간 비교 (equlas & hashcode)

동일성 비교 : 인스턴스의 참조 값을 비교한다 ( == 사용) 동등성 비교 : 인스턴스의 값을 비교한다. (equals() 사용) 인스턴스 형태인 값 타입의 경우 equals()를 사용하여 동등성을 비교해야한다. Address addr1 = new Address("city", "street", "10000"); Address addr2 = new Address("city", "street", "10000"); System.out.println("addr1 == addr2 = " + (addr1 == addr2)); // false System.out.println("addr1.equals(addr2) = " + addr1.equals(addr2)); // false Object 클래스에 선언한 equal..

[JPA] 임베디드 내장 타입 @Embadded 와 불변 객체

회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소 도시, 주소 번지, 주소 우편번호를 가진다고 가정해본다. 이름 근무 시작일 근무 종료일 주소 도시 주소 번지 주소 우편번호 하지만, 근무 시작일과 근무 종료일 그리고 도시, 번지, 우편번호는 종목이 비슷하다는 생각이 들게된다. 엔터티를 설명하게 될때 회원 엔티티는 이름, 근무기간, 주소 를 가진다 라고 추상화 하여 간략하게 설명할 수 있다. 이것들을 공통적으로 묶어낼 수 있는것을 임베디드 타입이라고 정의할 수 있다. @Entity(name = "USERS") @Setter @Getter @ToString public class User { @Id @GeneratedValue @Column(name = "USER_ID") private Long id;..

[JPA] @ManyToMany와 한계점 극복

관계형 데이터베이스는 정규화된 테이블 2개만으로 M:N 관계를 표현할 수 없다. 중간에 연결 테이블을 추가해서 1:M M:1 관계로 풀어내야 한다. User (회원)이 있고 Product (상품)이 있다고 가정해보자. 하나의 회원은 여러개의 상품을 구매할 수 있고, 하나의 상품은 여러 회원에 의해 구매될 수 있는 상황이 발생한다. 반면, 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계가 가능해진다. User는 List로 Product들을 가질수 있고, Product는 List로 User들을 가질 수 있다. @ManyToMany을 사용하고, @JoinTable을 사용하여 연결 테이블을 지정할 수 있게 된다. @ManyToMany @JoinTable(name = "USER_PRODUCT") private ..

[JPA] @OneToOne 단방향/양방향 - 외래키 정책 기준

@OneToOne 단방향 1:1 관계는 그 반대도 1:1이 된다. 따라서 주 테이블(Master)이나 대상 테이블(Detail) 중에 외래키를 어느쪽을 선택하든지 지정할 수 있다. (둘 중 한곳에만 넣어주면 된다.) 예를들어 User와 Team이 있다면, User에 외래키를 넣을 수도 있고, Team에 외래키를 넣을 수도 있다. 데이터베이스 입장에서는 외래키에 Unique 제약조건이 추가된것이 1:1관계가 된다. 회원이 락커를 하나만 사용할 수 있고, 락커 입장에서도 한명의 회원에 의해서만 사용되어지는 상황이 있다. 이때 회원에 락커의 PK를 FK(Unique)를 설정할 수 있거나, 락커에 회원의 PK를 FK(Unique)로 설정할 수 있다. 마치 다대일 단방향 연관관계 매핑과 유사하다. @Entity ..

[JPA] @OneToMany 단방향 / 양방향 - 외래키 관리 이해한 내용 정리

@Entity(name = "USERs") @Setter @Getter @ToString public class User { @Id @GeneratedValue @Column(name = "USER_ID") private Long id; private String username; } @Entity @Setter @Getter @ToString public class Team { @Id @GeneratedValue @Column(name = "TEAM_ID") private Long id; private String teamname; } @OneToMany 단방향 1:M관계에서는 연관관계의 주인이 1쪽으로 잡혀버린다. 외래키 자체는 M쪽에 존재하는데 외래키를 M이 관리하지 않고 1이 관리하게 된다. @J..

[JPA] @ManyToOne 단방향 / @ManyToOne <=> @OneToMany 양방향 정리

@Entity @Setter @Getter @ToString public class User { @Id @GeneratedValue @Column(name = "USER_ID") private Long id; private String username; } @Entity @Setter @Getter @ToString public class Team { @Id @GeneratedValue @Column(name = "TEAM_ID") private Long id; private String teamname; }​ @ManyToOne 단방향 M:1 관계에서 일반적으로 M에 1의 PK 가 외래키로 생성된다. JPA에서는 연관관계의 주인이 외래키를 관리하게 된다. 따라서 Foreign Key가 존재하는 M쪽이 ..