참고
- Getter, Setter 모두 제공하지 않고, 별도의 메서드를 제공하는 것이 이상적
- 하지만, 엔티티의 데이터를 조회하는 경우가 매우 많음
- Getter는 열어두는 것이 편리함
- Getter는 호출만으로 값이 바뀌지는 않음
- Setter를 호출하면 데이터가 변함
- Setter를 남용하면 엔티티의 변경을 추적하기 힘들어짐
- 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 한다.
📌 실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천
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")
private List<Order> orders = new ArrayList<>();
}
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "orders")
@Getter
@Setter
public class Order {
@Id
@GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate; // 주문 시간
@Enumerated(EnumType.STRING)
private OrderStatus status; // 주문 상태 [ORDER, CANCEL]
/*
#연관 관계 편의 메소드
양방향 관계에서 한번에 양쪽 다 세팅
*/
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
this.orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void setDelivery(Delivery delivery) {
this.delivery = delivery;
delivery.setOrder(this);
}
}
``
package jpabook.jpashop.domain;
import jpabook.jpashop.domain.item.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice;
private int count;
}
package jpabook.jpashop.domain.item;
import jpabook.jpashop.domain.Category;
import jpabook.jpashop.exception.NotEnoughStockException;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
public abstract class Item {
@Id
@GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
private String etc;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("B")
public class Book extends Item{
private String author;
private String isbn;
public static Book createBook(String name, int price, int stockQuantity, String author, String isbn){
Book book = new Book();
book.setName(name);
book.setPrice(price);
book.setStockQuantity(stockQuantity);
book.setAuthor(author);
book.setIsbn(isbn);
return book;
}
public void changeBookInfo(String name, int price, int stockQuantity,String author, String isbn) {
super.changeItemInfo(name, price, stockQuantity);
this.author = author;
this.isbn = isbn;
}
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@DiscriminatorValue("M")
public class Movie extends Item{
private String director;
private String actor;
}
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
public class Delivery {
@Id
@GeneratedValue
@Column(name = "delivery_id")
private Long id;
@OneToOne(mappedBy = "delivery",fetch = FetchType.LAZY)
private Order order;
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status; // READY, COMP
}
package jpabook.jpashop.domain;
public enum DeliveryStatus {
READY,COMP
}
package jpabook.jpashop.domain;
import jpabook.jpashop.domain.item.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
public class Category {
@Id
@GeneratedValue
@Column(name = "category_id")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id")
)
private List<Item> items = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
/*
#연관 관계 편의 메소드
양방향 연관 관계에서 한번의 setting으로 양방향 모두 설정
*/
public void addChildCategory(Category child){
this.child.add(child);
child.setParent(this);
}
}
실무에서는
@ManyToMany
사용 X
package jpabook.jpashop.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;
@Embeddable
@Getter
@AllArgsConstructor
public class Address {
private String city;
private String street;
private String zipcode;
protected Address(){}
}
참고
- 값 타입은 변경 불가능하게 설계해야 한다.
- @Setter 제거 → 생성자에서 값을 초기화해서 변경 불가능한 클래스를 만들자.
Setter
사용 X