임베디드 타입을 데이터베이스 테이블에 어떻게 매핑하는지 알아보자.
회사 테이블은 회사명, 주소, 자동차 기종, 자동차 제조 연도의 정보를 저장한다.
public class Company {
private Long id;
private String name;
private int year;
private String city;
private String street;
private String zipCode;
private String carModel;
private int carYear;
}
주소와 차에 관한 정보는 별도의 클래스로 추상화되는 게 좋아 보인다. 여기서, 별도의 테이블을 생성하지 않고 임베디드 타입을 사용하여 엔티티의 테이블과 매핑하여 해결할 수 있다.
@Embeddable 애노테이션을 사용하여 주소와 자동차의 세부 정보에 대한 추상화 클래스를 정의한다.
@Embeddable
public class Address {
private String street;
private String city;
private String zipCode;
}
@Embeddable
public class Car {
private String model;
private int year;
}
@Embdded 애노테이션을 추가하고, 별도의 필드 대신 Address와 Car를 사용하도록 변경한다.
@Entity
public class Company {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded
private Address address;
@Embedded
private Car car;
}
임베딩하고 데이터베이스 테이블에 매핑하는 엔티티를 생성하였다.
그러면 여기서 "JPA가 어떻게 데이터베이스 컬럼에 매핑할 것인가?" 라는 의문이 생겨야 한다.
가장 처음의 Company 클래스에는 carModel, carYear과 같은 필드가 있었고, Car 클래스에서는 model, year로 호출한다.
그래서 JPA는 이를 각각 carModel과 carYear에 매핑하려고 할 것이고, year 열과 컬럼명이 중복되어 충돌이 생길 수 있다.
그래서 @AttributeOverride와 @AttributeOverrides를 사용해서 매핑정보를 재정의해야 한다.
@Entity
public class Company {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded
private Address address;
@Embedded
@AttributeOverriedes({
@AttributeOverride(name = "model", column = @Column(name = "car_model")),
@AttributeOverride(name = "year", column = @Column(name = "car_year"))
})
private Car car;
}
이렇게 필드명이 겹치게 사용하는 경우가 많지 않을 것 같다. 그리고 @AttributeOverride를 사용하면 엔티티 코드가 지저분해질 수 있을 것 같다.