Category: 연관관계

0

JPA 연관 관계 - 고아 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 고아 객체란? 부모 엔티티와 연관관계가 끊어진 자식 엔티티 고아 객체 제거 부모 엔티티와 연관관계 가 끊어진 자식 엔티티를 자동으로 제거 @OneToOne, @OneToMany 만 가능하다. orphanRemoval = true @Entity@Getter@Setterpublic class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private List<Child> childList = new ArrayList<>(); public void addChild(Child child){ childList.add(child); child.setParent(this); }} public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Child child1 = new Child(); Child child2 = new Child(); Parent parent = new Parent(); parent.addChild(child1); parent.addChild(child2); em.persist(parent); em.flush(); em.clear(); Parent savedParent = em.find(Parent.class, parent.getId()); savedParent.getChildList().remove(0); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); }} Parent 에서 Child를 삭제할 때 delete 쿼리가 발생하게 된다.

0

JPA 연관 관계 - 즉시로딩과 지연로딩

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 N + 1 문제 하나의 쿼리(1) 를 날린 후 조회된 결과 값과 연관된 데이터 를 가져오기 위해 결과의 행수(N) 만큼 추가 쿼리가 발생하는 문제 즉시로딩 FetchType.EAGER 로 설정하게 되면 즉시 조회하게 된다. Join 해서 한방 쿼리로 가져오는 방법 데이터를 가져온 후 후속 쿼리를 날리는 기법, 해당 방법은 N + 1 문제를 일으킨다. @ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "TEAM_ID")private Team team; 프록시와 즉시로딩 주의 즉시 로딩을 적용하면 예상하지 못한 SQL 이 발생 즉시 로딩은 JPQL 에서 N + 1 문제를 일으킨다. JPA 가 만들어주는 쿼리는 내부적으로 최적화가 이뤄진다. JPQL 은 내부적으로 SQL 로 번역된 후 데이터를 가져온 다음에 연관 데이터에 대해 후속적으로 쿼리가 발생한다. 해결법 1 : fetch join 해결법 2 : @EntityGraph 해결법 3 : batch size @ManyToOne, @OneToOne 은 기본이 즉시 로딩 LAZY 로 설정한다. @OneToMany, @ManyToMany 는 기본이 지연 로딩 지연로딩

0

JPA 연관 관계 - 프록시 객체

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 프록시 객체의 특징 실제 클래스를 상속 받아서 만들어진다. 실제 클래스와 겉 모양이 같다. 사용자 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다. 프록시 객체는 실제 객체의 참조를 보관한다. 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다. 프록시 객체는 처음 사용할 때 한번만 초기화 프록시 객체를 초기화 할때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 초기화 되면 프록시 객체를 통해 실제 엔티티에 접근이 가능하다. 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야 한다. (== 비교 실패, 대신 instance of 사용) 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference() 를 호추랳도 실제 엔티티를 반환한다. 영속성 컨텍스트의 도움을 받을 수 없는 준 영속 상태일때, 프록시를 초기화 하면 문제 발생 org.hibernate.LazyInitializationException 예외를 터트린다. em.find() vs em.getReference() em.find() 데이터 베이스를 통해 실제 엔티티 객체를 조회한다. em.getReference() 데이터 베이스 조회를 미루는 가짜(프록시) 엔티티 객체 를 조회한다. public class JpaMain { public static void main(String[] ars) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("hello"); EntityManager em = entityManagerFactory.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); try { Member member = new Member(); member.setUsername("hello"); em.persist(member); em.flush(); em.clear(); Member savedMember = em.find(Member.class, 1L); printMemberAndTeam(savedMember); transaction.commit(); } catch (Exception e) { transaction.rollback(); } finally { em.close(); } entityManagerFactory.close(); } private static void printMember(Member member){ System.out.println("member = " + member.getUsername()); } private static void printMemberAndTeam(Member member) { String username = member.getUsername(); System.out.println("username = " + username); Team team = member.getTeam(); System.out.println("team = " + team.getName()); }}

0

JPA 연관 관계 - 일대다

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 공통 Mapping 정보를 관리하기 위한 MappedSuperclass Entity 에 공통적으로 들어가는 Mapping 정보를 관리해 코드가 중복해서 작성하는 것을 방지하기 위해 사용하는 어노테이션 상속관계 Mapping 이 아니다. 부모 클래스를 상속 받는 자식 클래스에 Mapping 정보만 을 제공한다. 직접 생성해서 사용할 일이 없으므로 추상클래스(abstract) 를 사용하는 것이 좋다. MappedSuperclass 클래스를 상속 받기 위해서는 같은 @MappedSuperclass 를 사용한 클래스나 @Entity 을 이용한 클래스만 상속이 가능하다. 요구 사항 모든 Entity 에는 생성자, 생성일, 수정자, 수정일 정보가 들어가야 한다. 모든 Entity 에 공통적으로 들어가는 Mapping 정보 를 관리하기 위한 BaseEntity 클래스를 생성한다. @MappedSuperclasspublic abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate;} 공통 Mapping 정보는 상속 을 통해 현재 Entity 에 적용할 수 있다.

0

JPA 연관 관계 - 다대일

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 다 대 일연관관계 매핑시 고려사항 다중성 단방향, 양방향 연관관계 주인 테이블 외래키 하나로 양쪽 조인 가능 사실 방향이라는 개념이 없음 객체 참조용 필드가 있는 쪽으로만 참조 가능 한쪽만 참조하면 단방향 양쪽이 서로 참조하면 양방향 연관관계 주인

0

JPA 연관 관계 - 상속 관계 Mapping

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 JPA 상속 관계 Mapping 관계형 데이터 베이스는 상속 관계가 없다. 슈펴타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사하다. 상속관계 Mapping : 객체의 상속 관계와 DB 의 슈퍼타입 서브타입 관계를 Mapping 슈퍼타입 서브타입 논리 모델을 객체의 상속관계를 물리 모델로 구현하는 방법 객체의 상속관계를 슈퍼타입 서브타입 모델로 구현하는 방법은 3가지 방법이 있다. 전략 설명 조인 전략 각각 테이블로 변환 (연관 관계로 관리) 단일 테이블 전략 통합 테이블로 변환 (하나의 테이블로 관리) 구현 클래스마다 테이블 전략 서브타입 테이블로 변환 사용하는 어노테이션 @Inheritance @DiscriminatorColumn(name=”DTYPE”) @DiscriminotorValue @Inheritance 전략

0

JPA 연관 관계 - 영속성 전이 Cascade

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 JPA 영속성 전이 Cascade Cascading 이란, 특정 Entity 에 작업을 수행했을 때, 같은 작업이 연관된 Entity 에도 일어나는 것을 의미한다. 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다. 엔티티를 연속화 할때 연관된 엔티티도 함께 영속화 하는 편리함을 제공한다. 영속성 전이 옵션 CascadeType.ALL 상위 Entity 에서 발생한 모든 작업을 하위 Entity 로 모두 전파 CascadeType.PERSIST 상위 Entity 를 영속화 하는 작업이 일어 날때 하위 Entity 도 같이 영속화 한다. CascadeType.MERGE 상위 Entity 에서 발생한 Merge 작업을 하위 Entity 까지 Merge 작업을 전파한다. CascadeType.REMOVE 상위 Entity 를 삭제할 때 하위 Entity 까지 삭제한다. CascadeType.REFRESH DataBase 로부터 상위 Entity 를 다시 읽어올때 하위 Entity 까지 다시 읽어온다. CascadeType.DETACH 상위 Entity 를 영속성 컨텍스트에서 제거할 때 하위 Entity 까지 같이 제거한다. @Entity@NoArgsConstructor@AllArgsConstructor@Setter@Getterpublic class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "person", cascade = CascadeType.ALL) private List<Phone> phones = new ArrayList<>(); public void addPhone(Phone phone){ phones.add(phone); phone.setPerson(this); }} @Entity@Builder@NoArgsConstructor@AllArgsConstructor@Getter@Setterpublic class Phone { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; public String phoneNumber; @ManyToOne @JoinColumn(name = "PERSON_ID") public Person person;}

0

JPA 연관 관계 - @MappedSuperclass

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 공통 Mapping 정보를 관리하기 위한 MappedSuperclass Entity 에 공통적으로 들어가는 Mapping 정보를 관리해 코드가 중복해서 작성하는 것을 방지하기 위해 사용하는 어노테이션 상속관계 Mapping 이 아니다. 부모 클래스를 상속 받는 자식 클래스에 Mapping 정보만 을 제공한다. 직접 생성해서 사용할 일이 없으므로 추상클래스(abstract) 를 사용하는 것이 좋다. MappedSuperclass 클래스를 상속 받기 위해서는 같은 @MappedSuperclass 를 사용한 클래스나 @Entity 을 이용한 클래스만 상속이 가능하다. 요구 사항 모든 Entity 에는 생성자, 생성일, 수정자, 수정일 정보가 들어가야 한다. 모든 Entity 에 공통적으로 들어가는 Mapping 정보 를 관리하기 위한 BaseEntity 클래스를 생성한다. @MappedSuperclasspublic abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate;}

0

JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 양방향 연관관계의 문제점 객체에서는 각기 다른 객체에서 참조하는 객체를 업데이트 하는 방법이 두 가지가 발생한다. 양방향 연관관계의 해결 방법 객체의 두 관계중 하나를 연관관계의 주인 으로 지정해 주인만이 외래 키를 관리하게 한다.(등록, 수정)주인이 아닌 쪽은 읽기만 가능하다 양방향 연관관계 주인 정하기 Foreign Key (외래키) 가 있는 곳을 주인으로 정해라 연관관계의 주인은 mappedBy 속성을 사용할 수 없다. 연관관계 주인이 아니면 mappedBy 속성을 사용할 수 있다.

0

JPA 연관 관계 - 양방향 연관관계

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 객체와 테이블이 관계를 맺는 차이 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로다른 단방향 관계 2개 다.테이블은 외래키 하나 로 두 테이블의 연관관계를 관리한다. 객체 : 연관관계 2개 (단방향 2개) 회원 —> 팀 연관관계 1개 (단방향) 팀 —> 회원 연관관계 1개 (단방향) 테이블 : 연관관계 1개 (양방향 1개) 회원 <—> 팀의 연관관계 1개 (양방향) 양방향 연관관계로 설계하기1:N 연관관계 Mapping OneToMany 어노테이션을 이용해 1:N 연관관계를 Mapping 한다. mappedBy 속성을 이용해 연관된 Entity 클래스 내 field 이름을 넣어준다. @Entitypublic class Team { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "TEAM_ID") private Long id; private String name; @OneToMany(mappedBy = "team") private List<Member> members = new ArrayList<>();}

0

JPA 연관 관계 - 객체 관계 모델링하기

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 외래키를 객체 내 Field 값 으로 모델링 @Entitypublic class Team { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "TEAM_ID") private Long id; @Column private String name;} @Entitypublic class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "MEMBER_ID") private long id; @Column(name = "USERNAME") private String username; @Column(name = "TEAM_ID") private Long teamId; // 외래키를 Field 값으로 갖는다.} Member 가 소속된 Team 정보 가져오기 Member 가 소속된 Team 정보를 가져오기 위해서는 Member Id를 이용해 해당 Member 객체를 가져와 저장된 Team Id를 가져온 후 해당 Team Id를 이용해 Member가 소속된 Team 을 조회해야 한다. Team team = new Team();team.setName("TeamA");entityManager.persist(team);Member member = new Member();member.setUsername("member1");member.setTeamId(team.getId());entityManager.persist(member);Member findMember = entityManager.find(Member.class, member.getId());Long findTeamId = findMember.getTeamId();Team findTeam = entityManager.find(Team.class, findTeamId); 객체 지향 스럽지 못한 모델링

0

JPA 연관 관계 - 객체 지향 스럽게 모델링 하기

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 객체 지향 스럽게 모델링 하기 객체는 참조를 이용해 다른 객체를 가져올 수 있다. 한 객체내에 관련된 객체 정보를 가질 수 있도록 모델링한다. Member 에서 Team 정보를 가져올 때 Member 객체 내 참조 를 통해 정보를 가져올 수 있다. N:1 연관 관계를 명시할 때는 @ManyToOne 과 @JoinColumn 을 이용해 관계를 나타낸다. @Entitypublic class Member { @Id private long id; private String username; @ManyToOne @JoinColumn private Team team; // Member 객체 내에서 관련된 Team 객체를 관리할 수 있도록 변경} Member 가 소속된 Team 정보 가져오기

0

JPA 연관 관계

목차 JPA 연관 관계 - 고아 객체 JPA 연관 관계 - 즉시로딩과 지연로딩 JPA 연관 관계 - 프록시 객체 JPA 연관 관계 - @MappedSuperclass JPA 연관 관계 - 상속 관계 Mapping JPA 연관 관계 - 영속성 전이 Cascade JPA 연관 관계 - 양방향 연관관계와 연관과계의 주인 JPA 연관 관계 - 양방향 연관관계 JPA 연관 관계 - 객체 지향 스럽게 모델링 하기 JPA 연관 관계 - 객체 관계 모델링하기 JPA 연관 관계 JPA 연관 관계 테이블과 객체 간 패러타임 차이로 인해 생기는 문제가 있다. 그 중 대표적인게 테이블 연관관계 를 객체로 풀어내는 것테이블간의 연관관계를 객체 연관관계로 풀어내기 위해서는 아래 3가지 조건을 잘 이해해야 한다. 방향 테이블 연관관계는 양방향 객체의 연관관계는 단방향으로만 존재한다. 객체의 양방향 관계는 단방향 관계 2개를 이용해 만들어준다. 다중성 One To One(일대일) 1:1 One To Many(일대다) 1:N Many To One(다대일) N:1 Many To Many(다대다) N:M 연관관계의 주인 테이블 연관관계를 객체 양방향 연관관계로 만들기 위해서는 연관관계 주인 을 정해야 한다. 객체의 두 관계중 하나를 연관관계의 주인으로 지정해 주인만이 외래 키 를 관리하게 한다. 연관관계 주인은 외래키를 이용해 (등록, 수정) 등이 가능하지만 주인이 아닌 쪽은 읽기 만 가능하다 JoinColumn 어노테이션 외래키 를 매핑할 때 사용하는 어노테이션 속성 기능 기본 값 name 매필할 외래키 이름을 명시한다. 필드명 + _ + 참조하는 테이블 기본키 컬럼명 referencedColumnName 외래 키가 참조하는 대상 테이블 컬럼명 참조하는 테이블의 기본키 컬럼명 foreignKey 외래키 제약 조건을 직접 지정할 수 있다. unique, nullable, insertable, updatable, columnDefinition, table @Column 속성과 같다.