예제에서는 설명을 쉽게하기 위해 엔티티 클래스에 Getter, Setter를 모두 열고, 최대한 단순하게 설계
하지만 실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천
<aside> ✏️ [참고]
이론적으로 Getter, Setter 모두 제공하지 않고, 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적입니다.
하지만 실무에서 엔티티의 데이터는 조회할 일이 너무 많으므로, Getter의 경우 모두 열어두는 것이 편리합니다.
Getter는 아무리 호출해도 호출 하는 것 만으로 어떤 일이 발생하지는 않습니다.
하지만 Setter는 문제가 다릅니다. Setter를 호출하면 데이터가 변합니다. Setter를 막 열어두면 가까운 미래에 엔티티에가 도대체 왜 변경되는지 추적하기 점점 힘들어집니다. 그래서 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 합니다.
</aside>
우선 domain 패키지를 만듭니다. domain에 핵심 엔티티들을 쭉 넣을 것입니다.
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private long id;
private String name;
@Embedded
private Address address;
@OneToMany (mappedBy = "member") //...1
private List<Order> orders = new ArrayList<>();
}
<aside> ✏️ [참고]
엔티티의 식별자는 id 를 사용하고 PK 컬럼명은 member_id 를 사용했습니다.
엔티티는 타입(여기서는 Member )이 있으므로 id 필드만으로 쉽게 구분할 수 있습니다.
하지만 테이블은 타입이 없으므로 구분이 어렵습니다. 그리고 테이블은 관례상 테이블명 + id 를 많이 사용합니다.
참고로 객체에서 id 대신에 memberId 를 사용해도 됩니다. 중요한 것은 일관성입니다.
</aside>
package jpabook.jpashop.domain;
import lombok.Getter;
import javax.persistence.Embeddable;
@Embeddable //...1
@Getter //...2
public class Address {
private String city;
private String street;
private String zipcode;
//...[참고]
protected Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
내장 타입을 쓸 때는 @Embeddable
과 @Embedded
둘 중에 하나만 있어도 되지만 보통 둘 다 적어줍니다.
→ 자세히
Setter를 제공하지 않습니다.