엔티티 타입
- @Entity로 정의하는 객체
- 데이터가 변해도 식벼자로 지속해서 추적 가능
- 예)회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능
값 타입
- int , integer String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체
- 식별자가 없고 값만 있으므로 변경시 추적 불가
- 예) 숫자 100을 200으로 변경하면 완전히 다른 값으로 대체 된다.
1. 값 타입
- 자바 기본 타입(int ,double).
- 래퍼 클래스 (Integer , Long)
- String
- 임베디드 타입(embedded type , 복합 값 타입)
- 컬랙션 값 타입(collection value type)
임베디드 타입
- 새로운 값 타입을 직접 정의할 수 있다 .
- JPA는 임베디드 타입 이라 한다
- 주로 기본 값 타입을 모아서 만들어 복합 값타입이라고도 한다 .
- int, String 과 같은 값 타입
임베디드 타입 사용법
@ Embeddable : 값 타입을 정의하는 곳에 표시
@ Embedded: 값 타입을 사용하는 곳에 표시
기본 생성자 필수
임베디드 타입의 장점
- 재사용 가능
- 높은 응집도
- Period.isWork() 처럼 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있다 .
- 임베디드 타입을 포함한 모든 값 타입은 , 값 타입을 소유한 엔티티에 생명주기를 의존한다.
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
private String name;
//기간
@Embedded
private Period period;
//주소
@Embedded
private Adress adress;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "team_id")
private Team team;
}
멤버 테이블의 period adress 는 embedded타입으로 정의되어 있다 원하는 값들을 클래스로 만들고 사용하는 쪽 필드에 @Embedded를 달아주고 , 임베디드 클래스에는 @Embeddable 을 달아주면 된다 .
@Getter
@Setter
@NoArgsConstructor
@Embeddable
public class Period {
private LocalDateTime startDate;
private LocalDateTime endDate;
}
기본 생성자가 필수로 필요하다 . 임베디드 클래스의 필드로 엔티티가 들어갈 수 도 있다. 또 엔티티에서 사용하는 어노테이션 들을 사용할 수 있다 (@Column 으로 이름을 지정할 수도 있음)
임베디드 타입과 테이블 매핑
-임베디드 타입은 엔티티의 값일 뿐이다 .
-임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
-객체와 테이블을 아주 세밀하게 매핑 하는 것이 가능하다.
-잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다 .
한 엔티티에서 같은 Embedded 타입을 사용해야한다면?
//주소
@Embedded
private Address homeAddress;
@Embedded
@AttributeOverrides(value = {
@AttributeOverride(name = "zipcode",column = @Column(name = "work_zipcode")),
@AttributeOverride(name = "street",column = @Column(name = "work_street"))
})
private Address workAddress;
@AttributeOverrides 을 지정해 주면 된다 value로 필드명을 맵핑해주면 된다 .
위와 같은 임베디드 타입은 값 을 사용자가 객체로 만들어 지정한 것이다. 문제는 객체 타입이기 때문에 한 인스턴스를 공유해서 사용하면 한쪽에서 수정이 일어날 시에 그 인스턴스를 사용하는 다른곳에서도 변경이 일어난다 이를 막기위해 값을 공유하지 않고 새로운 인스턴스를 만들어서 사용할 수도 있지만 이것도 사이드 이펙트를 일으 킬수 있는 여지가 있기 때문에 임베디드 타입 같은 객체는 생성자로만 값을 설정하고 setter를 만들지 않는다던다 불변 객체로 만드는 것이 좋다
그렇다면 값을 바꿔야할때는 어떻할까
그떄는 이전 값을 복사하여 생성자 인자로 주고 필요한 필드만 값을 바꾸는 식으로 새로운 인스턴스를 만들던지 해야한다.
'JPA' 카테고리의 다른 글
JPA 공부 13 - 직접 쿼리를 작성하는 방법 (0) | 2021.06.06 |
---|---|
JPA 공부 12 - 값 타입 collection 사용 (0) | 2021.06.06 |
JPA 공부 10 - 영속성 전이 (cascade) (0) | 2021.06.05 |
JPA 공부 9 - 즉시로딩과 지연로딩 (0) | 2021.06.05 |
JPA 공부 8 - Proxy (0) | 2021.06.05 |