값타입


JPA 값 타입에는 JAVA 의 기본 값타입 (int, String)이 있고 사용자가 직접 정의한 임베디드(embedded type) 값 타입과 컬렉션(collection) 값 타입이 있습니다.
오늘은 이 값 타입에 대해서 정리 해보겠습니다.

임베디드(embedded type) 값 타입


  1. 임베디드 값 타입 사용(@Embedded)

    사용자가 직업 정의한 값 타입을 임베디드(embedded type) 값 타입 이라고 합니다. 회원 정보 엔티티를 사용 하여 임베디드 값 타입을 정의 해보겠습니다.

    • 어노테이션 정보

      어노테이션 설명
      @Embedded 값 타입을 사용 하는 곳에 설정
      @Embeddable 값 타입을 정의 하는 곳에 설정
    • 엔티티 클래스

        @Entity
        @Table(name="MEMBER")
        public class Member {
            @Id @GeneratedValue
            @Column(name = "MEMBER_ID")
            private long id;
                  
            @Column(name = "MEMBER_NAME")
            private String name;
                  
            @Embedded Period membershipPeriod;		//회원 등록 기간
            @Embedded Inbody memberInbody;			//회원 신체 정보
              
            //Constructor, getter, setter
        }
              
        @Embeddable
        public class Period {
            @Temporal(TemporalType.DATE) Date sDate;	//회원등록일
            @Temporal(TemporalType.DATE) Date eDate;	//회원종료일
            //Constructor, getter, setter
        }
              
        @Embeddable
        public class Inbody {
            @Column(name = "height")
            private int height = 0;		//키
            private int weight = 0;		//몸무게
            private int muscleMass = 0;	//근육량
            //Constructor, getter, setter
        }
      
    • 테스트 클래스

        Member member = new Member("홍길동");
        Inbody memberInbody = new Inbody(180, 80, 41);
        Period membershipPeriod = new Period(calendar.getTime(), calendar.getTime());
              
        member.setMemberInbody(memberInbody);
        member.setMembershipPeriod(membershipPeriod);
        teacher1.setMember(member);
        em.persist(member);	//영속성 상태 변경
      
    • 결과

      회원 등록 결과

      회원 기간과 회원 인바디 임베디드 값 타입을 생성 해보았습니다. 결과에서 처럼 임베디드 값타입은 회원 엔티티의 값일 뿐입니다.
      그렇기 때문에 회원 테이블에 자동으로 매핑 되어 값이 입력 된 것을 확인 하였습니다. 이처럼 임베디드 값타입을 활용 하면
      데이터 처리는 JPA 가 해주기 때문에 객체지향 적인 설계가 가능합니다.

  2. 임베디드 속성 재정의(@AttributeOverride)

    @AttributeOverride 어노테이션을 사용 하여 임베디드 값 타입의 매핑 정보를 재정의 할 수 있습니다. 회원 목표 몸무게 정보를 재정의 하여 사용 해보겠습니다.

    • 엔티티 클래스

        @Entity
        @Table(name="MEMBER")
        public class Member {
            @Id @GeneratedValue
            @Column(name = "MEMBER_ID")
            private long id;
                  
            @Column(name = "MEMBER_NAME")
            private String name;
                  
            @Embedded Period membershipPeriod;		//회원 등록 기간
            @Embedded Inbody memberInbody;			//회원 신체 정보
                  
            @Embedded
            @AttributeOverrides({
                @AttributeOverride(name = "height", column = @Column(name="GOAL_HEIGHT")),
                @AttributeOverride(name = "weight", column = @Column(name="GOAL_WEIGHT")),
                @AttributeOverride(name = "muscleMass", column = @Column(name="GOAL_MUSCLEMASS"))
            })
            Inbody memberGoalInbody;			//회원 목표 신체 정보
            //Constructor, getter, setter
        }
      
    • 테스트 클래스

        Member member = new Member("홍길동");
        Inbody memberInbody = new Inbody(180, 80, 41);
        Period membershipPeriod = new Period(calendar.getTime(), calendar.getTime());
              
        Inbody memberGoalInbody = new Inbody(180, 75, 45);
              
        member.setMemberInbody(memberInbody);
        member.setMembershipPeriod(membershipPeriod);
        member.setMemberGoalInbody(memberGoalInbody);
        em.persist(member);	//영속성 상태 변경
      
    • 결과

      회원 등록 결과


컬렉션 값 타입(@CollectionTable)


  1. 컬렉션 값 타입 사용

    하나 이상의 값 타입을 저장 할때는 컬렉션에 보관하여 사용 하면 됩니다.

    • 어노테이션 정보

      어노테이션 설명
      @ElementCollection 임베디드 콜렉션 인터페이스
      @CollectionTable 컬렉션 매핑 정보
    • 엔티티 클래스

        @Entity
        @Table(name="MEMBER")
        public class Member {
            @Id @GeneratedValue
            @Column(name = "MEMBER_ID")
            private long id;
                  
            @Column(name = "MEMBER_NAME")
            private String name;
                  
            @Embedded Period membershipPeriod;		//회원 등록 기간
            @Embedded Inbody memberInbody;			//회원 신체 정보
                  
            @ElementCollection
            @CollectionTable(name = "INBODY_INFO", joinColumns = @JoinColumn(name = "MEMBER_ID"))
            private List<Inbody> inbodyHistory = new ArrayList<>();
            //Constructor, getter, setter
        }
      
    • 테스트 클래스

        Member member = new Member("홍길동");
        Inbody memberInbody = new Inbody(180, 80, 41);
        Period membershipPeriod = new Period(calendar.getTime(), calendar.getTime());
              
              
        Inbody history1 = new Inbody(180, 78, 42);
        Inbody history2 = new Inbody(180, 75, 42);
              
        member.setMemberInbody(memberInbody);
        member.setMembershipPeriod(membershipPeriod);
              
        member.addInbodyHistory(history1);
        member.addInbodyHistory(history2);
                     
        em.persist(member);	//영속성 상태 변경
      
    • 결과

      회원 등록 결과


마무리


오늘은 JPA 값 타입에 대해서 정리 해보았습니다. 값타입은 식별자가 없고 생명 주기를 엔티티에 의존 하기때문에 엔티티를 삭제 하면 함께 삭제가 됩니다.
값타입을 사용 할때는 불변객체로 생성하여 공유 하지 않는 것이 안전 합니다.