실제 애플리케이션에서는 배송 정보와 같이 여러 엔티티에서 공통으로 사용되는 데이터가 존재합니다. JPA의 임베디드 타입 기능은 이런 중복된 칼럼들을 하나의 값 타입으로 묶어 재사용함으로써, 보다 객체지향적인 모델링을 가능하게 합니다. 본 포스팅에서는 @Embeddable@Embedded 어노테이션을 통해 Address, Name 등의 값 객체를 정의하고, 이를 엔티티에 포함시키는 방법과 @AttributeOverride를 사용하여 매핑 정보를 개별 엔티티에 맞게 재정의하는 방법을 살펴봅니다. 이를 통해 코드의 중복을 줄이고, 유지보수가 용이한 설계를 구현하는 방법을 소개합니다.

Embedded Type#

JPA에서는 새로운 값 타입을 직접 정의해서 사용 할 수 있습니다. 배송 관련 서비스에서 발송인(Sender), 수취인(Receiver)가 있을 경우 중복적으로 주소에 관련 칼럼들이 요구 됩니다. 이러한 중복적인 칼럼들을 자료형으로 규합해서 훨씬더 객체지향적으로 풀어 나갈 수 있을 거같습니다.

Receiver 클래스#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@Entity
public class Receiver {
@Id
@GeneratedValue
private long id;

@Embedded
private Name name;

@Embedded
private Address address;

@Embedded
private PhoneNumber phoneNumber;
...
}
  • Address, Name 새로운 타입을 직접 정의 했습니다.
  • @Embedded 어노테이션을 통해서 값 타입을 사용한다고 명시 했습니다.

Address 클래스#

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Embeddable
public class Address {

@Column(name = "city")
private String city;

@Column(name = "street")
private String street;

@Column(name = "zip_code")
private String zipCode;

}
  • Embeddable 어노테이션을 통해서 값 타입을 사용한다고 명시 했습니다.
  • 엔티티 객체와 거의 비슷합니다.

Receiver 클래스#

1
2
3
4
5
6
7
8
9
10
11

@Entity
public class Sender {
...
@Embedded
private Name name;

@Embedded
private Address address;
...
}
  • Receiver클래스에서 직접 정의한 Address를 쉽게 사용할 수 있습니다.

Name 클래스#

1
2
3
4
5
6
7
8
9
10
11
12
13

@Embeddable
public class Name {

@Column(name = "first_name")
private String first;

@Column(name = "last_name")
private String last;

public String getFullName() {
return this.first + this.last;
}
  • 클래로로 정의하면 다양한 부수적인 효과를 적용 시킬 수 있습니다.
  • 정말 간단한 예로 getFullName() 메소드로 full name을 얻을 수 있습니다. 해당 모델에 맞는 다양한 함수를 정의 할 수 있습니다.

@AttributeOverride 재정의#

1
2
3
4
5
6
7
8
9
10
11
12
13

@Entity
public class Sender {
...
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "sender_city")),
@AttributeOverride(name = "street", column = @Column(name = "sender_street")),
@AttributeOverride(name = "zip_code", column = @Column(name = "sender_zip_code"))
})
private Address address;
...
}
  • 임베디드 타입에 정의한 매핑정보를 재정의 하려면 @AttributeOverride를 사용하면 됩니다.
  • 해당 칼럼은 sender_city, sender_street, sender_zip_code 으로 생성됩니다.

결론#

JPA의 임베디드 타입 기능을 활용하면, 중복되는 값 칼럼들을 하나의 값 객체로 묶어 재사용함으로써 객체지향적인 모델링이 가능해집니다.
또한, @AttributeOverride를 통해 각 엔티티에 맞게 매핑 정보를 유연하게 재정의할 수 있어, 데이터베이스 설계와 유지보수가 더욱 용이해집니다.
이러한 접근 방식은 코드의 중복을 줄이고 가독성과 확장성을 높여주며, 복잡한 도메인 모델을 설계할 때 큰 도움을 줍니다.
따라서, 여러분의 애플리케이션에서도 효율적인 데이터 모델링을 위해 JPA 임베디드 타입 기능을 적극 활용해 보시기 바랍니다.