본 문서는 인프런의 자바 ORM 표준 JPA 프로그래밍 - 기본편 (김영한) 강의를 공부하며 작성한 개인 노트입니다.
@Entity
@Embeddable
- 값 타입을 정의하는 곳에 표시@Embedded
- 값 타입을 사용하는 곳에 표시Address.class
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
}
Member.class
@Entity
public class Member {
...
@Embedded
private Address homeAddress;
}
@AttributeOverride
- 속성 재정의
@Embedded
@AttributeOverrides({
@AttributeOverride(name="city",
column=@Column(name="WORK_CITY")),
@AttributeOverride(name="street",
column=@Column(name="WORK_STREET"))
@AttributeOverride(name="zipcode",
column=@Column(name="WORK_ZIPCODE"))
})
임베디드 타입이 null이면 매핑한 컬럼값은 모두 Null
값 타입은 단순/안전하게 다뤄야함
임베디드 타입과 같은 값 타입을 여러 엔티티에서 공유하면 위험함
Address copyAddress = new Address(address.getCity(), address.getStreet(), address.getZipcode());
값 타입 - 인스턴스가 달라도 그 안에 값이 같으면 같은것으로 침
==
사용equals()
사용equals()
의 기본은 ==
비교@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return Objects.equals(city, address.city) &&
Objects.equals(street, address.street) &&
Objects.equals(zipcode, address.zipcode);
}
equals()
를 구현할 거면 hashCode()
도 구현해야함
@Override
public int hashCode() {
return Objects.hash(city, street, zipcode);
}
@ElementCollection
, @collectionTable
사용@ElementCollection
@CollectionTable(name = "FAVORITE_FOOD", joinColumns =
@JoinColumn(name = "MEMBER_ID")
private Set<String> favoriteFoods = new HashSet<>();
값 타입 저장
try {
Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(new Address("homeCity", "street", "2941");
member.getFavoriteFoods().add("치킨");
member.getFavoriteFoods().add("족발");
member.getAddressHistory().add(new Address("old1", "street", "192391");
em.persist();
tx.commit();
}
값 타입 조회 (지연로딩)
try {
...
Member findMember = em.find(Member.class, member.getId());
tx.commit();
}
값 타입 수정
try {
...
// homeCity -> newCity
Address a = findMember.getHomeAddress();
findMember.setHomeAddress(new Address("newCity", a.getStreet(), a.getZipcode());
// 치킨 -> 한식
findMember.getFavoriteFoods().remove("치킨");
findMember.getFavoriteFoods().add("한식");
값 타입 제거
try {
findMember.getAddressHistory().remove(new Address("old1", "street", "10000"));
findMember.getAddressHistory().add(new Address("newCity1", "street", "10000"));
}
@Entity
@Table(name = "ADDRESS")
public class AddressEntity {
@Id @GeneratedValue
private Long id;
private Address address;
public AddressEntity(String city, String street, String zipcode) {
this.address = new Address(city, street, zipcode);
}
...
}
Member.class
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MEMBER_ID")
private List<AddressEntity> addressHistory = new ArrayList<>();
웬만하면 컬렉션은 사용하지 말자. 엔티티 사용하자.
엔티티 타입의 특징
값 타입의 특징
값 타입: address
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
// generate - getter, equals, hashCode
// equals 구현할 때는 getter 사용하는 옵션 사용이 좋음
}