[JPA] Embedded 활용하기

spring, jpa

JPA 에서 Embedded 활용하기 #

private String city; // 시
private String district; // 구
private String detail; // 상세주소
private String zipCode; // 우편번호

이는 DRY 법칙에 어긋나기에 새로운 객체를 생성한다.

@Embeddable // ★
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
    
    private String city;        // 시
    private String district;    // 구
    private String detail;      // 상세주소
    private String zipCode;     // 우편번호
}
@Embedded
private Address address;

그리고 findAll.forEach로 테스트를 진행해보면

create table user (
        ...
        city varchar(255),
        detail varchar(255),
        district varchar(255),
        zip_code varchar(255),
        ...

User(...address=null, ...)
@Column(name = "address_detail")
private String detail;      // 상세주소
   create table user (
        ...
        city varchar(255),
        address_detail varchar(255),
        ...
User(..., address=Address(city=서울시, district=노원구, detail=한글비석로, zipCode=11111), ...)
private String homeCity;
private String homeDistrict;
private String homeDetail;
private String homeZipCode;
@Embedded
private Address homeAddress;

@Embedded
private Address companyAddress;
@Test
void embedTest() {
    ...
    user.setHomeAddress(new Address("서울시", "노원구", "한글비석로", "11111"));
    user.setCompanyAddress(new Address("서울시", "성동구", "성수2로", "22222"));
}
@Embedded
@AttributeOverrides({
    @AttributeOverride(name = "city", column = @Column(name = "home_city")),
    @AttributeOverride(name = "district", column = @Column(name = "home_district")),
    @AttributeOverride(name = "detail", column = @Column(name = "home_address_detail")),
    @AttributeOverride(name = "zipCode", column = @Column(name = "home_zip_code"))
})
private Address homeAddress;

@Embedded
@AttributeOverrides({
    @AttributeOverride(name = "city", column = @Column(name = "company_city")),
    @AttributeOverride(name = "district", column = @Column(name = "company_district")),
    @AttributeOverride(name = "detail", column = @Column(name = "company_address_detail")),
    @AttributeOverride(name = "zipCode", column = @Column(name = "company_zip_code"))
})
private Address companyAddress;

위와 같이 User class 와 UserHistory class에 함께 @AttributeOverrides를 지정해준다.

그리고 UserEntityListener class에는 ↓와 같이 수정해주도록 하자.

userHistory.setHomeAddress(user.getHomeAddress());
userHistory.setCompanyAddress(user.getCompanyAddress());

이제 테스트를 돌려보면…

create table user (
    ...
    company_city varchar(255),
    company_address_detail varchar(255),
    company_district varchar(255),
    company_zip_code varchar(255),
    ...
    home_city varchar(255),
    home_address_detail varchar(255),
    home_district varchar(255),
    home_zip_code varchar(255),
    ...
    )
...
User(...homeAddress=Address(city=서울시, district=노원구, detail=한글비석로, zipCode=11111), 
    companyAddress=Address(city=서울시, district=성동구, detail=성수2로, zipCode=22222), userHistories=[])
...
UserHistory(...homeAddress=Address(city=서울시, district=노원구, detail=한글비석로, zipCode=11111), 
    companyAddress=Address(city=서울시, district=성동구, detail=성수2로, zipCode=22222))

이렇게 테스트 결과값이 도출되어 잘 동작하는것을 볼 수 있다.


그렇다면 address 필드에 null 값이 오면 어떻게 될까?

@Test
void embedTest() {
    ...
    User user1 = new User();
    user1.setName("josh");
    user1.setHomeAddress(null);
    user1.setCompanyAddress(null);

    userRepository.save(user1);

    User user2 = new User();
    user2.setName("jordan");
    user2.setHomeAddress(new Address());
    user2.setCompanyAddress(new Address());

    userRepository.save(user2);
    
    userRepository.findAll().forEach(System.out::println);
    userHistoryRepository.findAll().forEach(System.out::println);
    }

위와 같이 josh 에는 null 값을 집어넣고, jordan 에는 빈 객체를 넣어준다.

User(... name=josh,..., homeAddress=null,
companyAddress=null, userHistories=[])

User(... name=jordan,..., homeAddress=Address(city=null, district=null, detail=null, zipCode=null),
companyAddress=Address(city=null, district=null, detail=null, zipCode=null), userHistories=[])

결과값은 위와 같이 약간은 다르게 테스트 결과값이 도출되었다.

[6, 2021-12-27 19:50:10.861632, 2021-12-27 19:50:10.861632, null, null, null, null, null, null, null, null, null, null, josh> ]

[7, 2021-12-27 19:50:10.992431, 2021-12-27 19:50:10.992431, null, null, null, null, null, null, null, null, null, null, jordan>]
User(super=BaseEntity(createdAt=2021-12-27T20:49:55.690597, updatedAt=2021-12-27T20:49:55.690597), id=6, name=josh, email=null, gender=null, homeAddress=null, companyAddress=null, userHistories=[])

User(super=BaseEntity(createdAt=2021-12-27T20:49:55.816963, updatedAt=2021-12-27T20:49:55.816963), id=7, name=jordan, email=null, gender=null, homeAddress=null, companyAddress=null, userHistories=[])