○ @ManyToMany 애너테이션은 N 대 M 관계를 맺어주는 역할을 합니다.
○ 음식 Entity와 고객 Entity가 N 대 M 관계라 가정하여 관계를 맺어보겠습니다.
mappedBy="userList" 주의
외래키의 주인: 주문 테이블
• JPA는 연관관계가 설정된 Entity의 정보를 바로 가져올지, 필요할 때 가져올지 정할 수 있습니다.
○ 즉, 가져오는 방법을 정하게되는데 JPA에서는 Fetch Type
• LAZY는 지연 로딩으로 필요한 시점에 정보를 가져옵니다.
• EAGER는 즉시 로딩으로 이름의 뜻처럼 조회할 때 연관된 모든 Entity의 정보를 즉시 가져옵니다.
기본적으로 @OneToMany 애너테이션은 Fetch Type의 default 값이 LAZY로 지정되어있고 반대로 @ManyToOne 애너테이션은 EAGER로 되어있습니다.
뒤쪽이 Many면 디폴트가 LAZY(지연로딩)임. One이면 EAGER.
지연로딩엔 영속성 컨텍스트!!!
- 지연 로딩도 마찬가지로 영속성 컨텍스트의 기능 중 하나이다.
지연 로딩이 된 엔터티를 조회하려고 할 때는 영속성 컨텍스트(@Transactional)이 필수이다. (이전에 배울 때는 조회만 하는거면 상관 없었는데 여긴 다름)
• 영속성 전이란?
○ 영속 상태의 Entity에서 수행되는 작업들이 연관된 Entity까지 전파되는 상황을 뜻합니다.
영속성 전이를 적용하여 해당 Entity를 저장할 때 연관된 Entity까지 자동으로 저장하기 위해서는 자동으로 저장하려고 하는 연관된 Entity에 추가한 연관관계 애너테이션에 CASCADE의 PERSIST 옵션을 설정하면됩니다.
JPA에서는 이를 간편하게 처리할 수 있는 방법으로 영속성 전이(CASCADE)의 PERSIST 옵션을 제공합니다.
이거로 1번만 써도 쿼리문 인서트 3번 날라감.
이렇게 중괄호 이용해서 중복으로 넣어줄수도 있음.
○ CASCADE의 REMOVE 옵션을 적용하면 해당 Entity 객체를 삭제 했을 때 연관된 Entity 객체들을 자동으로 삭제할 수 있었습니다.
하지만 REMOVE 옵션 같은 경우 연관된 Entity와 관계를 제거했다고 해서 자동으로 해당 Entity가 삭제 되지는 않습니다.
• 후라이드 치킨 Entity 객체와 연관관계를 제거했지만 Delete SQL이 수행되지 않는 것을 확인할 수 있습니다.
• JPA에서는 이를 간편하게 처리할 수 있는 방법으로 orphanRemoval 옵션을 제공합니다.
• 추가로 orphanRemoval 옵션도 REMOVE 옵션과 마찬가지로 해당 Entity 즉, Robbie Entity 객체를 삭제하면 연관된 음식 Entity들이 자동으로 삭제됩니다. (Cascade 옵션도 가지고 있다는 얘기)
<주의사항>
• orphanRemoval이나 REMOVE 옵션을 사용할 때 삭제하려고 하는 연관된 Entity를 다른 곳에서 참조하고 있는지 아닌지를 꼭 확인해야합니다.
- A와 B에 참조되고 있던 C를 B를 삭제하면서 같이 삭제하게 되면 A는 참조하고 있던 C가 사라졌기 때문에 문제가 발생할 수 있습니다.
- 따라서 orphanRemoval 같은 경우 @ManyToOne 같은 애너테이션에서는 사용할 수 없습니다. (@ManyToMany도 안됨)
- ManyToOne이 설정된 Entity는 해당 Entity 객체를 참조하는 다른 Entity 객체들이 있을 수 있기 때문에 속성으로 orphanRemoval를 가지고 있지 않습니다. (Many에서 삭제하는 one에 해당하는게 자동으로 삭제 될거고, 그 one은 Many랑 연관된게 많으니까 문제 발생으로 이해했음)
orphanRemoval 이랑 cascade는 정말 고민 많이 해보고 사용 할 것!
@Scheduled : 지정한 특정 시점마다 메서드가 동작함.
@Scheduled(cron = "0 0 1 * * *") // 초 분 시 일 월 주 -> 매일 새벽 1시
public void updatePrice() throws InterruptedException {
-> @EnableScheduling 을 SpringBootApplication에 마찬가지로 넣어줘야함.
(cron: 운영체제에서 특정 시간마다 어떤 작업을 자동수행 해주고 싶을 때 사용하는 명령어.)
-> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/support/CronExpression.html 참고해서 만들어내면 됨
이렇게하면 10초에 한번으로 바뀌어서 확인해볼 수 있다.
회원 DB에 매핑되는 @Entity 클래스구현 (User, UserRoleEnum)
컨트롤러 추가하고 dto, repository, service 추가했음.
@ManyToOne(fetch = FetchType.LAZY) //ManyToOne의 디폴트는 EAGER -> 회원정보가 항상 필요한건 아니기 때문에 LAZY로
상품 등록 및 조회 구현에서 회원 정보 넘겨주도록 수정해야함.
Admin 계정은 등록한 상품을 모두 조회 할 수 있도록 추가적인 기능 구현
(처음, 마지막에 화살표 표시 눌러서 이동 안되게 해야하니까)
테스트 데이터 러너 -> 한번 사용한뒤 주석처리함