백엔드/JPA

JPA 6장 (@Embeddable)

한뜽규 2023. 3. 17. 00:28
728x90

@Embeddable annotation에 대해 배워보자.

 

테이블에 값을 저장할 때 

title date category publisher writer_name writer_mail
... ... ... ... ... ...

writer_name, witer_mail 같이 서로 묶이면 더 보기 편할 거 같은 column들이 있다.

이럴 때 @Embeddable을 사용한다.

@Embeddable은 엔티티가 아닌 타입을 한 개 이상의 필드와 매핑할 때 사용한다.

 

package user;

import jakarta.persistence.Embeddable;

@Embeddable
public class school {

    private String elementarySchool;
    private String middleSchool;
    private String highSchool;

    public school(String elementarySchool, String middleSchool, String highSchool) {
        this.elementarySchool = elementarySchool;
        this.middleSchool = middleSchool;
        this.highSchool = highSchool;
    }

    protected school() {

    }

	//getter..., setter...
}

예시를 보자.

학교와 관련된 column들을 school이라는 클래스에 묶었다.

당연히 여기서 변수 명들은 각자의 column명과 일치하거나, 일치하지 않는다면 @Column으로 mapping을 해주어야 한다.

그리고 school이라는 클래스에 @Embeddable을 달아준다.

 

이제 테이블에 해당하는 클래스를 작성하자.

package user;

import jakarta.persistence.*;

@Entity
@Table(name = "user")
public class user {

    @Id
    private String email;
    private String name;
    @Embedded
    private school school;

    protected user() {
    }

    public user(String email, String name, school school) {
        this.email = email;
        this.name = name;
        this.school = school;
    }

	//getter... setter...
}

그러고 Id에 해당하는 멤버에 @Embedded를 달아준다.

이렇게 정상적으로 생성과 조회가 되는 것을 볼 수 있다.

 

만약 여기 school에 null을 넣어준다면, school에 들어있는 column의 값들에도 모두 null이 들어가게 된다.

 

같은 @Embeddable 타입 필드가 두 개라면 어떻게 될까?

당연히 에러가 난다.

 

그럴 때는 뒤에 오는 column은 @AttributeOverride로 설정을 재정의 해줘야 한다.

package school;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;

@Embeddable
public class info {

    @Column(name = "eleaddr")
    private String addr;
    @Column(name = "elenum")
    private String num;

    protected info(){}

    public info(String addr, String num) {
        this.addr = addr;
        this.num = num;
    }
    //getter... setter...
}
package school;

import jakarta.persistence.*;

@Entity
@Table(name = "school_table")
public class school {

    @Id
    @Embedded
    private info elementInfo;

    @AttributeOverrides({
            @AttributeOverride(name = "addr", column = @Column(name = "midaddr")),
            @AttributeOverride(name = "num", column = @Column(name = "midnum")),
    })
    @Embedded
    private info midInfo;

    protected school () {}

    public school(info elementInfo, info midInfo) {
        this.elementInfo = elementInfo;
        this.midInfo = midInfo;
    }
}

이렇게 info에 mapping 되는 변수가 2개 있으면 하나를 @AttributeOverride로 재정의 해준다.

그러면 충돌이 일어나지 않고 정상적으로 생성, 조회가 되는 것을 볼 수 있다.