JPA의 데이터 타입

  • 엔티티 타입: @Entity로 정의하는 객체, 식별자를 통해 추적 가능
  • 값 타입: int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체, 식별자가 없고 추적 불가
    • 기본값 타입
      • 자바 기본 타입(int, double)
      • 래퍼 클래스(Integer)
      • String
    • 임베디드 타입(복합 값 타입)
    • 컬렉션 값 타입

1. 기본값 타입

  • 값 타입은 엔티티의 생명주기에 의존
  • 값 타입은 공유하면 안됨
  • 자바에서 기본 타입(primitive type)은 절대 공유되지 않음

2. 임베디드 타입(복합 값 타입)

임베디드 타입: 새로운 값 타입을 직접 정의한 것 ➡️ 값 타입

  • @Embeddable: 값 타입을 정의하는 곳에 표시
  • @Embedded: 값 타입을 사용하는 곳에 표시
  • 임베디드 타입은 기본 생성자가 필수
  • 임베디드 타입을 포함한 모든 값 타입은 엔티티의 생명주기에 의존하므로 엔티티와 임베디드 타입의 관계를 UML로 표현하면 컴포지션 관계가 됨
  • 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음
  • 임베디드 타입은 값 타입을 포함하거나 엔티티 참조 가능
  • @AttributeOverride: 임베디드 타입에 정의한 매핑정보 재정의 ➡️ 엔티티에 설정

3. 값 타입과 불변 객체

값 타입 공유 참조

  • 임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험 ➡️ 부작용

값 타입 복사

  • 값 타입의 실제 인스턴스인 값을 공유하는 것은 위험하기 때문에 값을 복사해서 사용
  • 임베디드 타입처럼 직접 정의한 값 타입은 객체 타입
  • 자바는 객체에 값을 댕입하면 항상 참조 값을 전달
  • 다라서 객체의 공유 참조는 피할 수 없기 때문에 객체의 값을 수정하지 못하도록 막아야 함

불변 객체

  • 객체를 불변하게 만들면 값을 수정할 수 없으므로 부작용 원천 차단 ➡️ 불변 객체
  • 생성자로만 값을 설정하고 수정자를 만들지 않으면 됨

4. 값 타입의 비교

- 동일성 비교: 인스턴스의 참조 값 비교, == 사용
- 동등성 비교: 인스턴스의 값을 비교, equals() 사용
  • 값 타입을 시뵤할 때는 동등성 비교 사용
  • 값 타입의 equals() 메소드를 재정의할 때는 모든 필드의 값을 비교하도록 구현
    ➕ hashcode()도 재정의

5. 값 타입 컬렉션

@Entity
public class Member {
	@Id @GeneratedValue
    private Long id;
    
    @Embedded
    private Address homeAddress;
    
    @ElementCollection
    @CollectionTable(name = "FAVORITE_FOODS",
    	joinColumns = @JoinColumn(name = "MEMBER_ID"))
    @Column(name = "FOOD_NAME")
    private Set<String> favoriteFoods = new HashSet<String>();
    
    @ElementCollection
    @CollectionTable(name = "ADDRESS",
    	joinColumns = @JoinColumn(name = "MEMBER_ID"))
    private List<Address> addressHistory = new ArrayList<Address>();
    
    // ...
}

@Embeddable
public class Address {

	@Column
    private String city;
    private String street;
    private String zipcode;
    
    //...
}
  • 값 타입 컬렉션 조회시 페치 전략은 LAZY가 기본
  • JPA 구현체들은 값 타입 컬렉션에 변경 사항이 발생하면, 값 타입 컬렉션이 매핑된 테이블의 연관된 모든 데이터를 삭제하고, 현재 값 타입 컬렉션 객체에 있는 모든 값을 데이터베이스에 다시 저장
  • 실무에서 값 타입 컬렉션이 매핑된 테이블에 데이터가 많다면 성능 저하
  • 추가로 값 타입 컬렉션을 마핑하는 테이블은 모든 컬럼을 묶어서 기본 키를 구성
  • 이를 해결하기 위해 새로운 엔티ㅣ를 만들어 일대다 관계로 설정
    ➕ 영속성 전이(Cascade) ➕ 고아 객체 제거(ORPHAN REMOVE)
@Entity
public class AddressEntity {
	
    @Id
    @GeneratedValue
    private Long id;
    
    @Embedded Address address;
    
    ...
}
profile
Backend Developer👩🏻‍💻

0개의 댓글