JPA
JPA @Embedded, @Embeddable ์ฌ์ฉํ๊ธฐ
์๋ฆฌ๊ฐ๋๐
2023. 3. 10. 23:54
์๋ฒ ๋๋ ํ์
- ์๋ฒ ๋๋ ํ์ ์ ๋ณตํฉ ๊ฐ ํ์ ์ผ๋ก ๋ถ๋ฆฌ๋ฉฐ ์๋ก์ด ๊ฐ ํ์ ์ ์ง์ ์ ์ํด์ ์ฌ์ฉํ๋ JPA์ ๋ฐฉ๋ฒ์ ์๋ฏธํฉ๋๋ค.
- ์๋์ ์ฝ๋๋ฅผ ๋ณด๋ฉด User์ํฐํฐ๋ id, ์ด๋ฆ, ์ด๋ฉ์ผ, ์ฑ๋ณ, ์ฃผ์์ ๋ณด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณ ์๋๋ฐ ์ฃผ์ ์ ๋ณด๊ฐ ๋์, ๊ตฌ, ์์ธ์ฃผ์, ์ฐํธ๋ฒํธ ๋ฑ์ผ๋ก ์ฌ๋ฌ๊ฐ์ ์ปฌ๋ผ์ผ๋ก ๋๋ ์ ธ ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. -> ์ด๋ ๊ฒ ์์ธํ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ๊ฐ๊ณ ์๋ ๊ฒ์ ๊ฐ์ฒด์งํฅ์ ์ด์ง ์์ผ๋ฉฐ ์์ง๋ ฅ์ ๋จ์ด๋จ๋ฆฝ๋๋ค.
- ์ด๋ด๋ ์๋ฒ ๋๋ ํ์ ์ ์ฌ์ฉํ๋ฉด ๋์ฑ๋ ๊ฐ์ฒด์งํฅ์ ์ธ ์ฝ๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
// user.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
private String name;
@NonNull
private String email;
@Enumerated(value = EnumType.STRING)
private Gender gender;
// ์ฃผ์ ์ ๋ณด
private String city; // ๋์
private String district; // ๊ตฌ
private String detail; // ์์ธ์ฃผ์
private String zipCode; // ์ฐํธ๋ฒํธ
}
@Embedded, @Embeddable
- ์๋ฒ ๋๋ ํ์ ์ ์ ์ฉํ๋ ค๋ฉด ์๋ก์ด Class๋ฅผ ๋ง๋ค๊ณ ํด๋น ํด๋์ค์ ์๋ฒ ๋๋ ํ์ ์ผ๋ก ๋ฌถ์ผ๋ ค๋ Attribute๋ค์ ๋ฃ์ด์ค ๋ค @Embeddable๋ฅผ ๋ถ์ฌ์ค์ผํฉ๋๋ค.
- ์ฌ์ฉ ๋ฐฉ๋ฒ
- @Embeddable : ๊ฐ ํ์ ์ ์ ์ํ๋ ๊ณณ์ ํ์
- @Embedded : ๊ฐ ํ์ ์ ์ฌ์ฉํ๋ ๊ณณ์ ํ์
- ์๋์ ์๋ฒ ๋๋ ํ์ ์ ์ ์ฉํ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ฃผ์์ ๊ด๋ จ๋ ์์ฑ๋ค์ด ํ๋์ ํ์ ์ผ๋ก ๋ฐ๊ปด ์ฌ์ฉ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ด๋ฅผ ๋ณด๋ฉด ์์ ์ฝ๋๋ณด๋ค ๋์ฑ ๋ ๊ฐ์ฒด์งํฅ์ ์ด๊ณ ์์ง๋ ์๋ ์ฝ๋๋ก ๋ฐ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
// user.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
private String name;
@NonNull
private String email;
@Enumerated(value = EnumType.STRING)
private Gender gender;
@Embedded
private Address address;
}
// Address.java
@Embeddable
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
// ์ฃผ์ ์ ๋ณด
private String city; // ๋์
private String district; // ๊ตฌ
@Column(name = "address_detail")
private String detail; // ์์ธ ์ฃผ์
private String zipCode; // ์ฐํธ๋ฒํธ
}
// ๋ฐ์ดํฐ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ
user.setAddress(new Address("์์ธ์", "๊ฐ๋จ๊ตฌ", "๊ฐ๋จ๋๋ก 123", "16427"));
- ์๋ฒ ๋๋ ํ์ ์ ์ฌ์ฉํ์ฌ๋ ๋์ผํ๊ฒ Column๋ค์ด ์์ฑ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
@AttributeOverride : ์์ฑ๋ช ์ฌ์ ์
- ๊ฐ์ ์ข ๋ฅ์ Attribute์ ๋ํด์ ์ค๋ณต๋ ์ฝ๋๋ฅผ ์ ์ ํ์ ์์ด ๊ฐ๋จํ๊ณ ์ง๊ด์ฑ์๊ฒ ์ ์ธ ๊ฐ๋ฅํฉ๋๋ค.
- ์์๋ก๋ ํ์ฌ์ ์ฃผ์, ์ง ์ฃผ์์ ์ฃผ์ ํํ๋ ์, ๊ตฌ, ์์ธ์ฃผ์, ์ฐํธ๋ฒํธ๋ก ๋์ผํ๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ @Embedded์ @AttributeOverrides, @AttributeOverride๋ฅผ ํตํด ํ๋์ class๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ ํํ์ ํ ์ ์์ต๋๋ค. (๊ฐ์ฒด์ ์ฌํ์ฉ)
- ์๋์ ์ฝ๋๋ ๊ฐ์ฒด๋ฅผ ์ฌํ์ฉํ๋ ๋์ @AttributeOverrides, @AttributeOverride๋ฅผ ์ฌ์ฉํด column์ ์ด๋ฆ์ ์ ๋ถ ์ฌ์ ์ํ์ฌ ์ฌ์ฉํ๊ธฐ์ ์ฝ๋๊ฐ ์ง์ ๋ถํด ๋ณด์ผ ์ ์์ต๋๋ค. -> ๊ฐ์ฒด๋ฅผ ์ฌํ์ฉ ํ์ง ์๊ณ ๋ฐ๋ก ์ ์ธํด์ ํ๋ ๋์ ๊น๋ํ๊ฒ ๋ณด์ด๋ ์ฝ๋๋ฅผ ์์ฑํ ์ง, ๊ฐ์ฒด์ ์ฌํ์ฉ์ ํ๋ ์ฝ๋๋ฅผ ์์ฑํ ์ง๋ ๊ฐ๋ฐ์๊ฐ ๊ฒฐ์ ํด์ผํฉ๋๋ค.
@Entity
public class User {
.....
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "city", column = @Column(name = "home_city")), // city๋ฅผ home_city๋ผ๋ column๋ช
์ผ๋ก ์ฌ์ฉ
@AttributeOverride(name = "district", column = @Column(name = "home_district")),
@AttributeOverride(name = "detail", column = @Column(name = "home_address_detail")),
@AttributeOverride(name = "zipCode", column = @Column(name = "home_zipCode"))
})
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_zipCode"))
})
private Address companyAddress;
.....
}
์ฃผ์ํ ์
@Embedded private Address homeAddress; @Embedded private Address companyAddress;
ํ๋์ class๋ฅผ ํตํด ์ฌ๋ฌ๊ฐ์ ์ ๋ณด๋ฅผ ๋ง๋ค๊ณ ์ถ์๋ฐ ์์ ๊ฐ์ด @AttributeOverrides, @AttributeOverride๋ฅผ ํตํด column๋ช ์ ์ฌ์ ์ํด์ฃผ์ง ์์ผ๋ฉด Repeated column in mapping for entity ์๋ฌ๊ฐ ๋์ค๋ ๊ผญ column๋ช ์ ์ฌ์ ์ํด์ค์ ์ฌ์ฉํด์ผํฉ๋๋ค.
์๋ฒ ๋๋ ํ์ ๊ณผ null
- ์๋ฒ ๋๋ ํ์ ์์ฒด๋ฅผ null๋ก ์ง์ ํ์ ๋์ ์๋ฒ ๋๋ ํ์ ์ ์์ฑ ๊ฐ์ null๋ก ์ค์ ํ์ ๋๋ ๋ชจ๋ ํด๋น column์ ๊ฐ์ด null๊ฐ์ผ๋ก ๋์ค๊ฒ ๋ฉ๋๋ค.
- ์๋์ ์ฝ๋๋ฅผ ์ํํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๊ด๋ จ column๋ค์ ๊ฐ์ด ๋ชจ๋ null์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
- ์ฆ, ์๋ฒ ๋๋ ํ์ ์ ๊ฐ์ฒด๊ฐ null์ธ ๊ฒฝ์ฐ ๋ด๋ถ์ ๋ชจ๋ column์ด null์ธ ๊ฒ๊ณผ ๋์ผํ๊ฒ ์ฒ๋ฆฌ๊ฐ ๋ฉ๋๋ค.
void embedTest() {
User user1 = new User();
user1.setName("jaeryeol");
user1.setHomeAddress(null);
user1.setCompanyAddress(null);
userRepository.save(user1);
User user2 = new User();
user2.setName("jaeryeol2");
user2.setHomeAddress(new Address());
user2.setCompanyAddress(new Address());
userRepository.save(user2);
userRepository.findAllRawRecord().forEach(a-> System.out.println(a.values()));
}
}
๊ฒฐ๊ณผ
User(super=BaseEntity(createdAt=2023-03-09T00:33:51.107644, updatedAt=2023-03-09T00:33:51.107644), id=6, name=jaeryeol, email=null, gender=null, city=null, district=null, detail=null, zipCode=null, homeAddress=null, companyAddress=null)
User(super=BaseEntity(createdAt=2023-03-09T00:33:51.164491, updatedAt=2023-03-09T00:33:51.164491), id=7, name=jaeryeol2, email=null, gender=null, city=null, district=null, detail=null, zipCode=null, homeAddress=null, companyAddress=null)