예제에서는 설명을 쉽게하기 위해 엔티티 클래스에 Getter, Setter를 모두 열고, 최대한 단순하게 설계

하지만 실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천

<aside> ✏️ [참고]

이론적으로 Getter, Setter 모두 제공하지 않고, 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적입니다.

하지만 실무에서 엔티티의 데이터는 조회할 일이 너무 많으므로, Getter의 경우 모두 열어두는 것이 편리합니다.

Getter는 아무리 호출해도 호출 하는 것 만으로 어떤 일이 발생하지는 않습니다.

하지만 Setter는 문제가 다릅니다. Setter를 호출하면 데이터가 변합니다. Setter를 막 열어두면 가까운 미래에 엔티티에가 도대체 왜 변경되는지 추적하기 점점 힘들어집니다. 그래서 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 합니다.

</aside>

우선 domain 패키지를 만듭니다. domain에 핵심 엔티티들을 쭉 넣을 것입니다.

Untitled

회원 엔티티

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<>();

}
  1. mappedBy 를 적어줍니다.

<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;
    }
}
  1. 내장 타입을 쓸 때는 @Embeddable@Embedded 둘 중에 하나만 있어도 되지만 보통 둘 다 적어줍니다.

    자세히

  2. Setter를 제공하지 않습니다.