본문 바로가기
백엔드

[Spring Boot] JPA 값 타입

by 육빔 2024. 9. 2.
728x90
반응형

JPA의 데이터 타입은 

 

엔티티 타입

값 타입

 

으로 구분 할 있다.

여기서 엔티티 타입은

우리가 @Entity를 붙이는 객체를 말하는 거고

 

값 타입은 자바 기본 타입이나 객체를 말한다.

1. 값 타입의 종류

JPA에서 값 타입은 크게 세 가지로 나눌 수 있습니다.

  1. 기본 값 타입(Basic Value Type)
    • JPA에서 제공하는 기본적인 값 타입으로, Java의 기본 데이터 타입(int, long, double, boolean 등)과 래퍼 클래스(Integer, Long, Double, Boolean 등), 그리고 String, Date, BigDecimal, BigInteger 같은 타입들이 이에 해당합니다.
    • 별도의 매핑 없이 엔티티의 속성으로 사용 가능하며, 데이터베이스 테이블의 컬럼과 직접적으로 매핑됩니다.
  2. 임베디드 타입(Embedded Type)
    • 임베디드 타입은 여러 속성을 하나의 객체로 묶어서 사용하는 복합 값 타입입니다.
    • Java 클래스 형태로 정의되며, 이 클래스는 엔티티에 포함되어 재사용될 수 있습니다.
    • @Embeddable 어노테이션을 사용하여 임베디드 타입을 정의하고, 엔티티에서는 @Embedded 어노테이션으로 이를 사용합니다.
@Embeddable
public class Address {
    private String city;
    private String street;
    private String zipcode;

}

@Entity
public class Member {
    @Id
    private Long id;

    @Embedded
    private Address address;

}

 

3. 컬렉션 값 타입(Collection Value Type)

  • 값 타입 컬렉션은 임베디드 타입이나 기본 값 타입을 여러 개 모아서 사용할 때 사용됩니다.
  • 주로 List, Set, Map 등의 컬렉션 형태로 사용되며, 컬렉션에 담긴 값 타입들은 JPA 엔티티의 일부분으로 간주됩니다.
  • 데이터베이스에서는 값 타입 컬렉션이 별도의 테이블로 매핑됩니다
@Entity
public class Member {
    @Id
    private Long id;

    @ElementCollection
    @CollectionTable(name = "favorite_foods", joinColumns = @JoinColumn(name = "member_id"))
    @Column(name = "food_name")
    private Set<String> favoriteFoods = new HashSet<>();

}

 

또한 이런 값 타입을 사용할때 주의점이 있다.

1. 값 타입의 공유 참조 문제

  • 공유 참조의 위험성: 값 타입을 여러 엔티티에서 공유하면 위험할 수 있습니다. 예를 들어, 두 엔티티가 같은 주소(Address) 객체를 참조하면 한 엔티티에서 주소를 변경할 때 다른 엔티티의 주소도 의도치 않게 변경될 수 있습니다. 이것은 **부작용(side effect)**을 초래할 수 있습니다.
  • 값 복사: 값 타입의 인스턴스를 직접 공유하지 않고 복사해서 사용해야 부작용을 방지할 수 있습니다. Java의 기본 타입(int, float 등)은 값을 대입할 때 복사되지만, 객체 타입(예: Address)은 참조 값(레퍼런스)이 전달되므로 직접적으로 복사되지 않습니다.

2. 불변 객체의 필요성

  • 불변 객체의 정의: 불변 객체(Immutable Object)는 생성된 이후로 상태가 변경될 수 없는 객체입니다. 한 번 값을 설정하면 그 값을 절대 바꿀 수 없습니다. 따라서 불변 객체는 수정이 불가능하므로 부작용을 원천적으로 차단할 수 있습니다.
  • 불변 객체의 장점: 불변 객체는 값을 공유하더라도 그 값을 변경할 수 없기 때문에, 부작용이 발생하지 않습니다. 이는 값 타입을 안전하게 사용할 수 있는 방법입니다.
  • 불변 객체의 구현: 불변 객체를 만들기 위해서는 객체의 모든 필드를 final로 선언하고, 생성자에서만 값을 설정하며, 이후에 값을 변경할 수 있는 메서드(수정자, setter)를 제공하지 않습니다.

 

@Embeddable
public class Address {
    private final String city;
    private final String street;
    private final String zipcode;

    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }

    public String getCity() {
        return city;
    }

    public String getStreet() {
        return street;
    }

    public String getZipcode() {
        return zipcode;
    }
}

 

728x90
반응형