// 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; // 우편번호
}
@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"));
@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명을 재정의해줘서 사용해야합니다.Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.example.jpa_study.entity.User column: city (should be mapped with insert="false" update="false") at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ... 107 more
void embedTest() {
User user1 = new User();
user1.setName("Seongwon");
user1.setHomeAddress(null);
user1.setCompanyAddress(null);
userRepository.save(user1);
User user2 = new User();
user2.setName("Seongwon2");
user2.setHomeAddress(new Address());
user2.setCompanyAddress(new Address());
userRepository.save(user2);
userRepository.findAllRawRecord().forEach(a-> System.out.println(a.values()));
}
}
결과
User(super=BaseEntity(createdAt=2021-10-13T00:33:51.107644, updatedAt=2021-10-13T00:33:51.107644), id=6, name=Seongwon, email=null, gender=null, city=null, district=null, detail=null, zipCode=null, homeAddress=null, companyAddress=null)
User(super=BaseEntity(createdAt=2021-10-13T00:33:51.164491, updatedAt=2021-10-13T00:33:51.164491), id=7, name=Seongwon2, email=null, gender=null, city=null, district=null, detail=null, zipCode=null, homeAddress=null, companyAddress=null)