Spring

11. 스프링 / 영속성 전이

공대키메라 2021. 7. 20. 23:51

 

 

 

 

소유자가 하나일 때는 casecaseType.ALL로 설정해서 

관련된 테이블에 정보를 다 넣어도 상관이 없음.

 

근데 이제 하나의 테이블만 연관된 것이 아닌 여러개가 하나의 테이블에 접근하고 소유자가 하나가

아닐 때는 사용하면 안됌~

 => 중구난방으로 쿼리가 들어감 ㅠㅠ

 

 

예시) 
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL,orphanRemoval = true)
private List<Child> childList = new ArrayList<>();

 

 

 

 

기본값 타입

 

JPA는 두개의 데이터 타입으로 분류가 가능하다

 

1. 엔티티 타입

@Entity로 정의하는 객체

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

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

 

2. 값 타입

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

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

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

 

값타입은 다시 크게 세가지로 분류가 가능하다. 

1. 기본값 타입

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

 - 래퍼 클래스(Integer, Long)

 - String

 

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

 

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

 

기본값 타입

  • 예) String name, int age
  • 생명주기를 엔티티에 의존
  • 예) 회원을 삭제하면 이름, 나이, 필드도 함께 삭제
  • 값 타입은 공유하면 X
  • 예) 회원 이름 변경시 다른 회원의 이름도 함계 변경되면 안됨

참고 : 자바의 기본 타입은 절대 공유가 안됌!

 

public class ValueMain{
	public static void main(String[] args){
    	
        Integer a1 = new Integer(10);
        Integer b1 = a1;
    
    	a1.setValue(20) // 만약에 있다고 가정
    
    	int a = 10;
        int b = a;
        
        a = 20;
        
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        
        System.out.println("===============");
        
        System.out.println("a1 = " + a1);
        System.out.println("b1 = " + b1);
    }
}

//결과
// a = 10
// b = 20

// a1 = 10  <= 같은 인스턴스를 공유함.
// b1 = 10

 

근데 이 이야기를 다시 왜하냐?

 

우선 들어보자옹

 

임베디드 타입(복합값 타입)

  • 새로운 값 타입을 직업 정의할 수 있음
  • JPA는 임베디드 타입(embedded type)이라 함
  • 주로 기본 값 타입을 모아서 만들어서 복합 값 타입이라고도 함
  • int, String과 같은 값 타입

예시)

 

위의 것을 밑에 처럼 묶어내는데 이것을 임베디드 타입이라고 한다. 

 

 

 

임베디드 타입 장점

1. 재사용

2. 높은 응집도

3. Period.isWork()처엄 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있음

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

 

 

밑에 Member.java를 확인해 보면 

주소랑 기간으로 따로 분리해서 나눌 수 있다.

주의사항이 있는데

기본 생성자는 반드시 있어야 함

package hellojpa;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.time.LocalDateTime;

@Entity //<= 아! 이건 JPA가 관리하는 객체! 라는걸 등록해주는 아이
public class Member extends BaseEntity{

//======================== 처음
    @Id @GeneratedValue
    @Column(name="MEMBER_ID")
    private Long id;

    @Column(name="USERNAME")
    private String username;

    //Period
    private LocalDateTime startDate;
    private LocalDateTime endDate;

    //주소
    private String city;
    private String street;
    private String zipcode;
    //======================== 처음
    // => 변경하면...
    
    @Id @GeneratedValue
    @Column(name="MEMBER_ID")
    private Long id;

    @Column(name="USERNAME")
    private String username;

    //Period
    @Embedded
    private Period workPeriod;

    //주소
    @Embedded
    private Address homeAddress;
}

//=========== Period.java
package hellojpa;

import javax.persistence.Embeddable;
import java.time.LocalDateTime;

@Embeddable
public class Period {

    private LocalDateTime startDate;
    private LocalDateTime endDate;
    
}
//=========== Period.java

//=========== Address.java
package hellojpa;

import javax.persistence.Embeddable;

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

    public Address() {
    }

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

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

  • 임베디드 타입은 엔티티의 값일 뿐이다
  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 객체와 테이블을 아주 세밀하게(find-grained)매핑하는 것이 가능
  • 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음

 

@AttributeOverride : 속성 재정의

 => 한 엔티티에서 같은 값 타입을 사용하면?

   - 컬럼 명이 중복됨

   - @AttributeOverrides, @AttributeOverride를 사용해서 컬러 명 속성을 재정의