JPA 값타입


값타입


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

Back to blog