JPA

[JPA] 17. 값 타입

inuma 2021. 1. 21. 21:52
프로젝트 git url github.com/rtef23/JpaStudy
필요 1. docker
2. docker-compose
프로젝트 정보 mysql : 5.7 - docker image
java : 1.8

 

JPA의 데이터 타입 분류

  • 엔티티 타입
    • @Entity로 정의하는 객체
    • 데이터가 변해도 식별자로 추적 가능
  • 값 타입
    • int, Integer, String과 같이 단순히 값으로 사용하는 자바 기본 타입 또는 객체
    • 식별자가 없고 값만 있으므로 변경시 추적 불가
    • 해당 값 타입을 소유한 엔티티에 생명주기를 의존한다.

 

값 타입

  • 값 타입은 복잡한 객체 세상을 단순화 하기 위해 만든 개념
    • > 값 타입은 단순하고 안전하게 사용할 수 있어야 한다.

기본값 타입

  • 종류
    • 자바 기본 타입(int, double, ...)
    • 래퍼 클래스(Integer, Double, ...)
    • String
  • 값 타입은 공유하지 않도록 해야한다.
    • example) 회원 이름 변경시, 다른 회원의 이름도 변경되면 안된다.
    • primitive type의 경우, 공유 안됨(값 복사)
    • 래퍼 클래스(String, Integer, ...)의 경우, 참조를 가지고 있기 때문에 공유가 가능, 하지만 공유하도록 하면 안된다.

 

임베디드 타입(Embedded Type; 복합 값 타입)

  • 새로운 값 타입을 직접 정의할 수 있음
  • 주로 기본 값 타입을 모아서 만들기 때문에 복합 값 타입(Composite Value Type)이라고도 함

  • Period, Address를 임베디드 타입이라 한다.
  • @Embeddable
    • ; 값 타입을 정의하는 곳에서 표시
  • @Embedded
    • ; 값 타입을 사용하는 곳에서 표시
  • 기본 생성자가 필수
  • 임베디드 타입이 null인 경우, 하위 값들은 null로 저장되게 된다.
  • 장점
    • 재사용 가능
    • 높은 응집도
      • Period.isWork()와 같이 해당 값 타입만 사용하는 의미있는 메소드를 만들 수 있음
@Entity
public class Member {
  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @Embedded
  private Period workPeriod;

  @Embedded
  private Address homeAddress;
  
  ...
}

@Embeddable
public class Period {
  private LocalDate startDate;
  private LocalDate endDate;

  public Period() {
  }
  
  ...
}

@Embeddable
public class Address {
  private String city;
  private String street;
  private String zipCode;

  public Address() {
  }
  
  ...
}
Member member = new Member();

member.setName("user-name-1");
member.setHomeAddress(new Address("city-1", "street-1", "zipcode-1"));
member.setWorkPeriod(new Period(LocalDate.now(), LocalDate.now().plus(3, ChronoUnit.DAYS)));

entityManager.persist(member);

 

임베디드 타입과 연관관계

  • 임베디드 타입은 엔티티 타입을 소유할 수 있다.(임베디드 타입도 소유가 가능하다.)

 

하나의 엔티티가 동일한 임베디드 타입을 가지게 되는 경우

  • 컬럼명이 중복됨
  • @AttributeOverrides, @AttributeOverride를 사용하여 컬럼명 속성을 재정의
@Entity
public class Member {
  @Embedded private Address homeAddress;

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name = "city", column = @Column(name = "work_city")),
    @AttributeOverride(name = "street", column = @Column(name = "work_street")),
    @AttributeOverride(name = "zipCode", column = @Column(name = "work_zipcode"))
  })
  private Address workAddress;
  
  ...
}
Member member = new Member();

member.setName("user-name-1");
member.setHomeAddress(new Address("city-1", "street-1", "zipcode-1"));
member.setWorkAddress(new Address("city-2", "street-2", "zipcode-2"));
member.setWorkPeriod(new Period(LocalDate.now(), LocalDate.now().plus(3, ChronoUnit.DAYS)));

entityManager.persist(member);

 

컬렉션 값 타입(Collection Value Type)

 

'JPA' 카테고리의 다른 글

[JPA] 19. 값 타입 컬렉션  (0) 2021.01.23
[JPA] 18. 값 타입 - 불변 객체  (0) 2021.01.21
[JPA] 16. 영속성 전이(CASCADE)  (0) 2021.01.18
[JPA] 15. 즉시 로딩과 지연 로딩  (0) 2021.01.18
[JPA] 14. Hibernate 프록시  (0) 2021.01.15