전체 글 280

값 타입, 값 타입 컬렉션

값 타입 공유 참조 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험하다 부작용이 발생한다. 회원1, 회원2가 같은 주소의 타입을 공유하고 있을 때 그 값으로 OldCity가지고 있었는데 city값을 NewCity로 변경하면 회원1, 회원2가 가지고 있는 주소의 값이 변경될 수 있다. 코드를 살펴보자 Address address = new Address("city" , "street", "10000"); Member member1 = new Member(); member1.setName("member1"); member1.setHomeAddress(address); em.persist(member1); Member member2 = new Member(); member2.setName("mem..

JPA 2023.09.01

임베디드 타입

임베디드 타입 새로운 값 타입을 직접 정의할 수 있음 JPA는 임베디드(embedded type) 타입이라 함 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함 int, String과 같은 특성의 값 타입 엔티티가 아니어서 변경하면 추적이 안된다 위와 같은 회원 엔티티가 있다고 보자 회원 엔티티의 필드를 보면 (startDate, endDate) = workPeriod, (city, street, zipcode) = homeAddress필드를 묶을 수 있다. 이렇게 묶을 수 있는 것이 임베디드 타입이다. Period, Address를 클래스를 만들어서 저장하면 된다. 임베디드 타입 사용법 @Embeddable : 값 타입을 정의하는 곳에 표시 @Embedded : 값 타입을 사용하는 곳에 표..

JPA 2023.08.31

기본값 타입

JPA는 데이터 타입을 2가지로 분류한다. 엔티티 타입 @Entity로 정의하는 객체 데이터가 변해도 식별자로 지속해서 추적가능 예) 회원 엔티티의 키나 나이 값을 변경해도 식별자(Id)는 유지되기 때문에 인식 가능 값 타입 int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체 식별자(id)가 없고 값만 있으므로 변경 시 추적 불가능 예) 숫자 100을 200으로 변경하면 완전히 다른 값으로 대체 값 타입 기본값 타입 자바 기본 타입(int, double) 래퍼 클래스 (Integer, Long) String 임베디드 타입 컬렉션 값 타입 기본값 타입 예) String name, int age 생명주기를 엔티티에 의존 예) 회원 엔티티를 삭제하면 이름, 나이 필드도 같..

JPA 2023.08.31

영속성 전이 : CASCADE, 고아객체

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때예) 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장 (persist)Parent와 Child 코드를 보자@Entitypublic class Parent { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "parent") private List childList = new ArrayList(); public void addChild(Child child) { child.setParent(this); childList.add(child); }@Entitypu..

JPA 2023.08.31

즉시 로딩과 지연 로딩

Member와 Team이 [N : 1] 연관 관계 매핑이 되어있는 상태에서 Member를 조회할 때 상항 Team을 같이 조회해야 할까? 비즈니스 로직이 단순 Member정보만 사용하는 경우에 Team 테이블도 Join해서 데이터를 가져오면 손해가 발생된다. LAZY을 사용하여 지연 로딩을 해보자 @Entity public class Member extends BaseEntity{ @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "USERNAME") private String name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TEAM_ID") priva..

JPA 2023.08.30

프록시와 연관관계 관리

Member와 Team이 연관관계로 매핑이 되어있는 상황을 예시로 생각해 보자 비즈니스 로직에 따라 Member를 조회하고 자주 Team을 찾는 경우, Member만 사용을 많이 하는 경우가 있다. 각 경우에 따라 전자는 Team까지 같이 가져오는 SQL을 하는 것이 후자는 Member만 가져오는 SQL을 작성하는 것이 유리하다. 이를 해결하지위해 JPA는 지연로딩과 프록시를 사용한다. 프록시 em.find() vs em.getReference() em.find : 데이터베이스를 통해서 실제 엔티티 객체를 조회 Member와 Team 테이블을 Join해서 가져온다 em.getReference() : 데이터베이스 조회를 미루는 가짜(프락시) 엔티티 객체 조회 getReference하는 시점에는 DB에 쿼리..

JPA 2023.08.30

MappedSuperclass

MappedSuperclass의 사용을 아래의 예시를 통해 알아보자 객체의 입장에서 id, name의 필드가 계속 나올 때 BaseEntity에 속성만 두고 상속해서 사용할 때 사용한다 DB는 각각 따로 사용한다. 이렇게 공통매핑 정보가 필요할 때 사용한다. 다른 예시를 보자 만약 Team과 Member 클래스의 공통 정보 필드가 아래와 같이 있다고 보자 private String createdBy; private LocalDateTime createDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate; 공통 정보를 처리하기 위해 BaseEntity라는 클래스를 만들자 @MappedSuperclass public abstr..

JPA 2023.08.30

상속관계 매핑

관계형 데이터베이스에는 상속 관계가 없다. 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사하다. 상속관계 매핑 : 객체의 상속과 구조의 DB의 슈퍼타입 서브타입관계를 매핑 상속관계 매핑 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법 각각 테이블로 변환 -> 조인 전략 통합 테이블로 변환 -> 단일 테이블 전략 서브타입 테이블로 변환 ->구현 클래스마다 테이블 전략 위 3개의 방법 어느 것을 사용하더라도 JPA에서는 매핑이 가능하다. 각 Entity를 만들어 보자 @Entity public class Item { @Id @GeneratedValue private Long id; private String name; private int price; } @Entity public ..

JPA 2023.08.29

다양한 연관관계 매핑

연관관계 매핑 시 고려사항에는 3가지가 있다 다중성 (다대일, 일대다, 일대일, 다대다) 단방향, 양방향 테이블 외래 키 하나로 조인 가능 사실 방향이라는 개념이 없음 객체 참조용 필드가 있는 쪽으로 참조 가능 한쪽만 참조하면 단방향 양쪽이 서로 참조하면 양방향 (사실 단방향 2개) 연관관계의 주인 (양방향) 테이블은 외래키 하나로 두 테이블이 연관관계를 맺음 객체 양방향 관계는 A->B, B->A처럼 참조가 2군데 객체 양방향 관계는 참조가 2군데 있음. 둘 중 테이블의 외래 키를 관리할 곳을 지정해야 함 연관관계의 주인 : 외래 키를 관리하는 참조 주인의 반대편 : 외래 키에 영향을 주지 않음, 단순 조회만 가능 다대일 [N : 1] N이 연관관계 주인 단방향 DB입장에서 팀이 1이고 MEMBER가 ..

JPA 2023.08.29

연관관계 매핑, 단방향, 양방향

연관관계가 필요한 이유 예제 시나리오를 통해 알아보자 회원과 팀이 있다. 회원은 하나의 팀에 소속될 수 있다. 회원과 팀은 다대일 관계이다. 만약 연관관계가 없이 객체를 테이블에 맞추어 모델링을 하면 아래와 같이 된다. 이렇게 설계를 하게 되면 Member객체에 teamId 필드를 통해 Team을 참조해야 한다. 만약 멤버의 팀을 조회하려면 아래와 같은 코드를 수행해야 한다. //조회 Member findMember = em.find(Member.class, member.getId()); Team findTeam = em.find(Team.class, findMember.getTeamId()); 이런 코드는 객체 지향적인 방법이 아니다. 객체는 참조를 사용해서 객체를 찾고 테이블은 외래키로 조인을 사용해..

JPA 2023.08.28