Spring JPA 값 타입

2025. 6. 23. 18:26Spring Boot

JPA의 데이터 타입 분류

JPA는 크게 2가지의 타입으로 분류하고 있습니다.

 

엔티티 타입

※@Entity로 정의하는 객체

※데이터가 변해도 식별자로 지속해서 추적 가능

※예시) 회원 엔티티의 키나 나이 값을 변경해도 식별자로 인식 가능.

 

값 타입

※int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체

※식별자가 없고 값만 있으므로 변경시 추적 불가

※예시)숫자 100을 200으로 변경하면 완전히 다른 값으로 대체

 

값 타입 분류 (크게 3가지로 분류 할 수 있습니다)

1.기본값 타입

  - 자바 기본 타입(int, double)

  - 래퍼 클래스(Integer, Long)

  - String 

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

3.컬렉션 값 타입(collection value type)

 

기본값 타입

예) String name, int age

생명주기를 엔티티의 의존.(예시 -> 회원을 삭제하면 이름, 나이 필드도 함께 삭제)

값 타임은 공유 X ->예)회원 이름 변경시 다른 회원의 이름도 함께 변경되면 안됨.

 

임베디드 타입

-새로운 값 타입을 직접 정의할 수 있음

-JPA는 임베디드 타입이라고 불림

-주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함

-int, String과 같은 값 타입

 

임베디드 타입의 장점

1.재사용이 가능함.

2.높은 응징도

3.해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있음.

4.임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 엔티티에 생명주기를 의존함.

 

임베디드 타입 활용

@Entity
public class Member {
    @Id
    @GeneratedValue
    private Long id;
    private String userName;

    private LocalDateTime start;
    private LocalDateTime end;

    private String zip;
    private String address;
}

우선 Member 엔티티를 만들어봤습니다. 

엔티티를 보면 start, end를 묶고 zip, address를 묶으면 더 재사용성과 유지보수, 메서드를 만들기가 용이합니다.

임베디드 타입을 통해 엔티티를 수정해보겠습니다.

 

@Entity
public class Member {
    @Id
    @GeneratedValue
    private Long id;
    private String userName;
    @Embedded
    private Period period;
    @Embedded
    private address address;

}

@Embeddable
public class Period {
    private LocalDateTime start;
    private LocalDateTime end;
}

@Embeddable
public class address {
    private String zip;
    private String address;
}

이러한 방식으로 설정하면 임베디드 값 타입을 적용할 수 있습니다.

이러한 방식으로 실행하면 처음에 Member를 정의한 것처럼 DB에 저장할 수 있습니다.

 

임베디드 타입과 테이블 매핑

1.임베디드 타입은 엔티티의 값일 뿐이다.

2.임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.(핵심)

3.객체와 테이블을 아주 세밀하게(FIND-GRAINED) 매핑하는 것이 가능하다.

4.잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다.

※가장 핵심은 임베디드 타입을 사용하나 사용하지 않나 매핑하는 테이블은 같다.

 

@AttributeOverride:속성 재정의

-한 엔티티에서 같은 값 타입을 사용한다면? -> 이때 사용하는것이 @AttributeOverride를 바탕으로 재 정의해주면 된다.

 

임베디드 타입과 null

-임베디드 타입의 값이 null이면 매핑한 컬럼 값은 모두 null

 

값 타입 공유 참조

-임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 위험함.

-부작용(side effect) 발생.

 

값 타입 복사

-값 타입을 실제 인스턴스인 값을 공유하는 것은 굉장히 위험합니다. -> 실제로 내가 1개의 객체에 엔티티를 수정하면 여러 값이 변경될 수 있습니다. -> 그렇기 때문에 인스턴스를 복사해서 사용하는 것이 최선입니다.

 

객체 타입의 한계

1. 항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용을 피할 수 없다.

2.문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본 타입이 아니라 객체 타입이다.

3.자바 기본 타입에 값을 대입하면 값을 복사한다.

4.객체 타입은 참조 값을 직접 대입하는 것을 막을 방법이 없다.

5.객체의 공유 참조는 피할 수 없다.

 

불변 객체

1.객체 타입을 수정할 수 없게 처음부터 만들면 부작용을 원천 차단.

2.값 타입은 불변 객체로 설계해야함.

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

4.(중요) 생성자로만 값을 설정하고 수정자(Setter)를 만들지 않으면 됨

   - 실제로 Setter를 통해 값을 변경하는 과정에서 가장 큰 실수가 나오고 있습니다. 애초에 생성자로만 설정하고 setter를 제한하면 불변 객체를 만들 수 있습니다.

 

'Spring Boot' 카테고리의 다른 글

웹 스코프  (1) 2025.06.21
빈 스코프  (0) 2025.06.20
서블릿 필터  (0) 2025.04.10
로그인 구현(Java + JPA + MySQL)  (0) 2025.02.24
JPA Entity 기본키 매핑  (0) 2025.02.06