참고-실전! 스프링 부트와 JPA활용1 -웹 어플리케이션 개발
설계된 것을 보고 먼저 설계 후 강의를 들어봤는데 계속 빼먹는 부분이들이 있어 메모🗒️
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
new ArrayList<>();
빼먹지 말자!null point exception
이 나지 않는다.(null 문제에서 안전)Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(member);
System.out.println(member.getOrders().getClass());
//출력 결과
class java.util.ArrayList
class org.hibernate.collection.internal.PersistentBag
getOrders()
처럼 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 따라서 필드레벨에서 생성하는 것이 가장 안전하고, 코드도 간결하다. @Id @GeneratedValue
@Column(name = "member_id")
private Long id;
@Column(name = "member_id")
⭐️ @Embeddable
@Getter
public class Address { //값타입은 변경 불가능하게 설계해야 한다.
private String city;
private String street;
private String zipcode;
@Embedded
private Address address;
public abstract class Item {
Item
을 추상 클래스로 만들고 Album
, Book
, Movie
는 상속 받아 사용하도록 해야 한다.@Entity
@Getter @Setter
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")```
코드를 입력하세요
public abstract class Item {
- 부모클래스에 `@Inheritance(strategy = InheritanceType.SINGLE_TABLE)` 를 넣어준다.
- 싱글테이블 전략이기 때문에 album, book, movie를 구별할 수 있게 해줘야 한다.
`@DiscriminatorColumn(name = "dtype")` 을 부모테이블에 넣어 준다.
- 자식 클래스에 아무것도 넣지 않으면 기본 클래스 이름으로 `dtype`이 반영되지만 명칭을 줄 수 있다.
`@DiscriminatorValue("B")`
---
### <span style="color:coral">enum 타입</span>
⭐️ enum 타입은 사용하는 곳에 꼭 `@Enumerated(EnumType.STRING)` 넣어줘야 한다.
```java
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
ORDINAL
인데 이대로 사용하면 나중에 추가로 다른 상품 같은게 추가될 때 순서가 밀려서 꼬일 수 있다. (실무에서는 사용하지 않는다.)
public class Category
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
JoinTable(name = ""category_item)
joinColumns = @JoinColumn(name = "category_id")
inverseJoinColumns = @JoinColumn(name = "item_id")
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
mappedBy
해주면 된다.public class Category {
@ManyToOne //내 부모니까 manyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
cascade = CascadeType.ALL
은 persist를 전파한다.cascade = CascadeType.ALL
하면 persist(order)하나 만으로 모두 persist 된다. public class Order {
@OneToOne(fetch = LAZY, cascade = ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
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;
}