@Bean
Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
고오오급..
@Component
@RequiredArgsConstructor
public class InitDb {
private final InitService initService;
@PostConstruct
public void init() {
initService.dbInit1();
initService.dbInit2();
}
@Component
@Transactional
@RequiredArgsConstructor
static class InitService {
private final EntityManager em;
public void dbInit1() {
System.out.println("Init1" + this.getClass());
Member member = createMember("userA", "서울", "1", "1111");
em.persist(member);
Book book1 = createBook("JPA1 BOOK", 10000, 100);
em.persist(book1);
Book book2 = createBook("JPA2 BOOK", 20000, 100);
em.persist(book2);
OrderItem orderItem1 = OrderItem.createOrderItem(book1, 10000, 1);
OrderItem orderItem2 = OrderItem.createOrderItem(book2, 20000, 2);
Delivery delivery = createDelivery(member);
Order order = Order.createOrder(member, delivery, orderItem1, orderItem2);
em.persist(order);
}
public void dbInit2() {
Member member = createMember("userB", "진주", "2", "2222");
em.persist(member);
Book book1 = createBook("SPRING1 BOOK", 20000, 200);
em.persist(book1);
Book book2 = createBook("SPRING2 BOOK", 40000, 300);
em.persist(book2);
OrderItem orderItem1 = OrderItem.createOrderItem(book1, 20000, 3);
OrderItem orderItem2 = OrderItem.createOrderItem(book2, 40000, 4);
Delivery delivery = createDelivery(member);
Order order = Order.createOrder(member, delivery, orderItem1, orderItem2);
em.persist(order);
}
private Member createMember(String name, String city, String street, String zipcode) {
Member member = new Member();
member.setName(name);
member.setAddress(new Address(city, street, zipcode));
return member;
}
private Book createBook(String name, int price, int stockQuantity) {
Book book1 = new Book();
book1.setName(name);
book1.setPrice(price);
book1.setStockQuantity(stockQuantity);
return book1;
}
private Delivery createDelivery(Member member) {
Delivery delivery = new Delivery();
delivery.setAddress(member.getAddress());
return delivery;
}
}
@RestController
@RequiredArgsConstructor
public class OrderSimpleApiController {
private final OrderRepository orderRepository;
@GetMapping("/api/v1/simple-orders")
public List<Order> ordersV1(){
List<Order> all =orderRepository.findAllByString(new OrderSearch());
return all;
}
}
order 안에 member가 fetch = LAZY로 설정되어있기 때문이다.
이건 지연로딩이라 멤버를 가져올때 프록시객체로 가져오는데 이것은 가짜 객체이고 그러므로 오류가 발생( ByteBuddyInterceptor이라는 클래스의 객체가 들어가있다.)
이러고 나중에 order안의 member를 접근할때 그제서야 디비에서 가져옴~~(프록시 초기화)
그래서 호출해서 띄워줄때 오류가 발생
이 경우 하이버네이트한테 이 작동을 하지말라고 명령해야함
- 그걸위해 하이버네이트5모듈등록~
`implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'`
- 이것을 build.gradle에 추가하고
```
@Bean
Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
```
- 이것을 스프링 실행 메인함수에 집어넣어서 실행해준다
- 그러면 오류는 안나지만 LAZY설정된 객체들은 이제 모두 null 로뜸
- 이것은 이제 저 설정이 지연로딩되는 객체들을 일단 null로 뽑아내자는 설정이기떄문
- 설정을 변경하면 바로 다 뜨게할수있다.
- 하지만 그렇게되면 엔티티가 노출되어버림
- 필요한것만 뽑아쓰도록하자 ~~~/
@GetMapping("/api/v1/simple-orders")
public List<Order> ordersV1(){
List<Order> all =orderRepository.findAllByString(new OrderSearch());
for (Order order : all){
order.getMember().getName(); // LAZY 강제 초기화
}
return all;
}
@GetMapping("/api/v2/simple-orders")
public List<SimpleOrderDto> ordersV2() {
List<Order> orders = orderRepository.findAllByString(new OrderSearch());
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(Collectors.toList());
return result;
}
@Data
static class SimpleOrderDto {
private Long orderId;
private String name;
private LocalDateTime orderDate; //주문시간 private OrderStatus orderStatus;
private Address address;
private OrderStatus orderStatus;
public SimpleOrderDto(Order order) {
orderId = order.getId();
name = order.getMember().getName();
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress();
} }
public List<Order> findAllWithMemberDelivery() {
return em.createQuery(
"select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class)// 앞에는 쿼리문 뒤에는 가져올 객체를 담을 클래스~~
.getResultList();
}
@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> ordersV3() {
List<Order> orders = orderRepository.findAllWithMemberDelivery();
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(Collectors.toList());
return result;
}
@Data
public class SimpleOrderQueryDto {
private Long orderId;
private String name;
private LocalDateTime orderDate; //주문시간 private OrderStatus orderStatus;
private Address address;
private OrderStatus orderStatus;
public SimpleOrderDto(Long orderId, String name, LocalDateTime
orderDate, OrderStatus orderStatus, Address address) {
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
}
}
public List<OrderSimpleQueryDto> findOrderDtos() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.simplequery.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address)"
+ " from Order o" +
" join o.member m" +
" join o.delivery d", OrderSimpleQueryDto.class)
.getResultList();
}
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> ordersV4() {
return orderRepository.findOrderDtos();
}