[JPA] 값 타입

JUJU·2024년 7월 3일
0

Spring Boot

목록 보기
13/13
본 포스트는 김영한 개발자님의 JPA 프로그래밍 강의를 듣고 정리한 것입니다.
※ 코드는 강의에서 사용된 것과 다릅니다.
jaewon-ju Github Address

✏️ 데이터 타입

JPA에는 2가지 데이터 타입이 존재한다.


1. 엔티티 타입

엔티티 타입은 @Entity 로 정의하는 객체이다.

  • PK로 관리하기 때문에, 데이터가 변해도 지속적인 추적이 가능하다.
    ex) Menu의 Title이 바뀌어도 PK를 통해 인식 가능하다.

2. 값 타입

값 타입은 자바 기본 타입이나 객체이다.
ex) int, Integer, String

  • 식별자가 없고 값만 존재한다.
  • 변경 시 추적이 불가능하다.

⚠️ 값 타입은 공유하면 안된다!!!


값 타입은 다시 3가지 유형으로 분류할 수 있다.

  1. 기본값 타입
  2. 임베디드 타입
  3. 컬렉션 값 타입

값 타입들은 생명주기를 엔티티에 의존한다.

3가지 값 타입에 대해서 알아보자.




✏️ 값 타입

1. 기본값 타입

  • 자바 기본 타입 (int, double)
  • 래퍼 클래스 (Integer, Long)
  • String

2. 임베디드 타입

임베디드 타입

: 기본값 타입을 모아서 정의한 새로운 타입

예를 들어, EducationContent 엔티티에 존재하는 createTimeupdateTime 필드를 하나로 묶어서 TimeInfo 라는 새로운 임베디드 타입으로 정의할 수 있다.

⚠️ 새로운 엔티티를 만드는게 아니다!


  • 임베디드 타입을 정의하는 곳에 @Embeddable 어노테이션을 붙인다.
  • 임베디드 타입을 사용하는 곳에 @Embedded 어노테이션을 붙인다.
  • 임베디드 타입은 기본생성자가 필수적으로 존재해야 한다!

@Embeddable
public class TimeInfo {
	private LocalDateTime createTime;
	private LocalDateTime updateTime;
    
    public TimeInfo() {}
}
@Entity
public class EducationContent {
	@Id @GeneratedValue
    private Long id;
    
    @Embedded
    private TimeInfo timeInfo;
}

⚠️ 임베디드 타입으로 컬럼들을 묶는다 해도, 실제 DB의 테이블에 변화는 없다!
즉, education_content 테이블에는 여전히 createTime, updateTime 컬럼이 존재한다.


3. 컬렉션 값 타임

엔티티가 아닌 값들의 그룹을 저장하는 타입

EdcuationContent 마다 여러개의 댓글(Comment)을 가진다면, 다음과 같이 만들어 줄 수 있다.

@ElementCollection
@CollectionTable(name = "comment",
				 joinColumns = @JoinColumn(name = "education_content_id"))
private Set<String> comments = new HashSet<>();
  • @ElementCollection, @CollectionTable 어노테이션을 사용한다.
  • 실무에서는 컬렉션 값 타입 대신에, 1:N 관계를 사용하는 것이 좋다.
  • 예를 들어, 하나의 EducationContent에 다수의 Comment 가 존재한다면 Comment를 하나의 엔티티로 만드는 것이 좋다.



✏️ 불변 객체

값 타입들은 서로 공유하면 안된다!!

컨텐츠 A의 업데이트 시간이 변경되었다고 해서 컨텐츠 B까지 변경하면 안된다.
다음의 코드는 임베디드 값 타입을 공유한 예시이다.

TimeInfo timeInfo = new TimeInfo("2024-07-01T15:36:11","2024-07-01T15:36:11")

EducationContent content1 = new EducationContent();
content1.setTitle("A");
content1.setTimeInfo(timeInfo);

EducationContent content2 = new EducationContent();
content2.setTitle("B");
content2.setTimeInfo(content1.getTimeInfo()); // content1의 값을 공유

위와 같은 코드를 사용하면, content1이 TimeInfo 를 변경하면 content2에도 영향을 준다.
따라서, 다음과 같이 값을 복사해서 사용해야 한다.


TimeInfo copyTime = content1.getTimeInfo();
content2.setTimeInfo(new TimeInfo(copyTime.getCreateTime(), copyTime.getUpdateTime())); // 값을 복사해서 사용

또 다른 방법으로, 불변 객체를 사용하면 객체의 공유를 막을 수 있다.


■ 불변 객체

불변 객체

: 생성 시점 이후 절대 값을 변경할 수 없는 객체

setter를 정의하지 않거나, private로 정의하면 불변객체를 만들 수 있다.




REFERENCE

자바 ORM 표준 JPA 프로그래밍 - 김영한 개발자님

profile
개발자 지망생

0개의 댓글

관련 채용 정보