30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
영속성 컨텍스트 유지관련 질의
15분 37초에 나온, 주문자가 모두 같은 책을 주문했을 경우엔 영속성 컨텍스트에 값이 있으니까, 쿼리가 하나만 나가도 된다, 는 말과 관련해서 영속성 컨텍스트가 언제 사라지고 다시 생성되는지 헷갈려서 질문드립니다! 요청마다 영속성 컨텍스트가 열리고 닫힌다, 로만 이해하고 있다보니 헷갈리는 듯합니다. 코드는 다음과 같습니다. @RestController @RequiredArgsConstructor public class OrderApiController { private final OrderRepository orderRepository; @GetMapping("/api/v2/orders") public List<OrderDto> ordersV2() { List<Order> orders = orderRepository.findAllByString(new OrderSearch()); List<OrderDto> result = orders.stream() .map(o -> new OrderDto(o)) .collect(Collectors.toList()); return result; } @Getter static class OrderDto { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; private List<OrderItemDto> orderItems; public OrderDto(Order order) { orderId = order.getId(); name = order.getMember().getName(); orderDate = order.getOrderDate(); orderStatus = order.getStatus(); address = order.getDelivery().getAddress(); orderItems = order.getOrderItems().stream().map(orderItem -> new OrderItemDto(orderItem)).collect(Collectors.toList()); } } @Getter static class OrderItemDto { private String itemName; private int orderPrice; private int count; public OrderItemDto(OrderItem orderItem) { itemName = orderItem.getItem().getName(); orderPrice = orderItem.getOrderPrice(); count = orderItem.getCount(); } } } api/v2/orders 로 요청이 들어오면 우선, orderRepository.findAllByString 메소드가 실행되면서 영속성 컨텍스트가 열리고, 메소드가 종료되며 닫히고 orderDto 를 생성하는 과정에서 Member를 db에서 가져오며 영속성 컨텍스트가 열렸다가 닫히고 Delivery 를 가져오며 다시 열리고 닫히고 OrderItemDto를 생성하며 item 을 가져오며 영속성 컨텍스트가 닫히는 거라고 생각하고 있습니다. 정확히 어디에서 영속성 컨텍스트가 열리고 닫히는지 알 수 있을까요??
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
springboot 로그 설정 질문 있습니다.
springboot 에서 http log 보는 설정이 뭐였죠? 어디선가 언급해줬는데 아무리 찾아봐도 어디인지 모르겠네요. 검색해도 안나오고 ...
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
FORCE_LAZY_LOADING false 적용이 안됩니다.
Hibernate5Module Bean을 추가했는데도 json에서 lazy loading이 발생하네요. Entity 관계는 전부 LAZY 입니다. 무엇 때문인지 알 수 없어서 질문 올려봅니다. plugins { id 'org.springframework.boot' version '2.4.9' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'jpabook' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-devtools' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //JUnit4 추가 testImplementation("org.junit.vintage:junit-vintage-engine") { exclude group: "org.hamcrest", module: "hamcrest-core" } } test { useJUnitPlatform() }
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Dto 반환 질문입니다
그 예전에 영한님께서 JSON으로 반환 할 때 쿼리를 통해서 얻은 값을 그대로 반환하지 말고 클래스로 묶어서 반환하라고 하셨던게 기억이 납니다. 쿼리를 통해서 얻은 결과가 예를들어 List<PersonDto> name : ~~~ age : ~~~ address: ~~ 이런식으로 되어 있을때 이 리스트를 그대로 반환하면 JSON 형식이 배열로 시작해서 그 후에 값을 수정 할 수 없다고 들었던거 같은데요!! 질문이 있습니다 저 List<PersonDto>를 감싸는 하나의 클래스를 만들때 예를 들어서 class PersonExmpleDto{ private ArrayList<PersonDto> persondto; ] 이런식으로 반환 할 때 클래스 이름을 어떻게 해야 할 지 모르겠습니다.... 쿼리를 통해서 얻은 List로 묶은 PersonDto를 하나의 클래스에서 반환하고자 할 때 클래스의 네이밍은 어떤식으로 하나요?class PersonListDto{ private ArrayList<PersonDto> persondto;} 이런식으로 하나요...??
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
pdf 툴 관련 질문드립니다
안녕하세요 강의를 매일 들으며 즐겁게 공부하는 직장인입니다. 원래 강의 내용을 노션에다가 정리를 했었는데 불편함을 느껴서 강의 도중 pdf 비슷하게 정리를 하는 툴이 있던데 혹시 그것이 무엇인지 여쭤봐도 될까요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
추상클래스와 @transactional 질문입니다.
안녕하세요 영한님 JPA 수업을 정말 잘듣고 있으며 이 수업을 듣고 제가 실무에서 적용을 하면서 인정받고 있어서 정말 감사합니다.실무를 하던 중 문제는 해결하였으나 원리가 잘 이해가 안가는 부분이 있는데 구글리을 해도 좀처럼 나오지 않아 이렇게 질문을 드립니다 문제가 되는 코드는 실무코드라 간추린 버전으로 올리겠습니다. 추상클래스 입니다. method1()은 구현을 했으며 method2()는 추상메소드입니다 구현클래스이고 추상 메소드인 method2만 오버라이딩하여 구현했습니다 이상황에서 ExampleClass ex = new ExampleClass(); ex.method1(); 이렇게 실행했을 때 저는 생각한 것이 - ExampleClass는 상속을 받았으므로 method1()이 있다. - ExampleClass에 @transactional을 걸었으므로 method1()에도 @transactional이 걸릴 것이다 그런데 막상 실행해보니 트랜잭션이 실행되지 않더군요 그래서 여러가지시도를 한 결과 부모클래스인 AbstractExampleClass에 @transactional을 걸으니 해결되었었습니다. 그런데 문제는 해결했으나 원리가 잘 이해가 되지 않습니다. - ex.method1()를 실행하면 ExampleClass에 @transactional이 있으므로 AOP에서 트랜잭션을 실행해주는 것이 아닌가? 이런 생각이 들더군요 아마 제가 @transactional과 AOP의 자세한 구동원리를 잘 몰라서 그런거 같은데 왜 ExampleClass에 @transactional을 붙이면 안되고 추상클래스에 붙여야 하는지 원리를 자세히 알 수 있을까요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
transaction 내에서의 ConcurrentHashMap
안녕하세요 영한님, 실무에서는 Map의 동시성 문제를 해결하기위해 ConcurrentHashMap을 사용한다고 들었습니다. 혹시 지금처럼 한번에 조회한 값을 Map으로 만들어 주는 상황에서도 ConcurrentHashMap을 사용하나요? Transaction은 독립적인 존재인걸로 알고있어 동시성문제가 발생하지 않을 것 같긴한데 궁금해서 여쭤봅니다 (제가 transaction에 대해 잘못 알고 있는 것일수도 있을것 같아서요)
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@Transactional(readOnly=true) 설정에 대한 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요, 최근 부하테스트를 진행하며 성능개선을 해보려하고 있습니다. 그 중 단순 DB 조회 API에 대해 테스트를 진행하고 있는데, 스레드 덤프를 확인한 결과 SessionImpl.doFlush()가 호출되는 것을 보고 트랜잭션이 끝나는 시점에 자동으로 flush가 호출되는 것을 발견했고, 때문에 readOnly 설정이란 것을 찾아서 설정하고 다시 테스트를 진행했습니다. 반복해서 테스트를 진행해 봤는데, readOnly를 설정하지 않았을때가 TPS가 높게 측정이 됩니다. 왜 그런지 알 수 있을까요.. 그림은 순서대로 readOnly를 설정하지 않았을 때와 설정했을 때 입니다. 테스트 대상 API의 코드는 아래 링크의 getMovieList() 입니다. https://github.com/hapHollys/booook/blob/main/src/main/kotlin/com/haphollys/booook/presentation/controller/MovieController.kt
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
병렬로 DB 쿼리하기
안녕하세요 영한님 수강한 강의를 바탕으로 프로젝트를 진행하고 있습니다. nodejs개발 경험 있어서 Promise.all과 같은 병렬로 여러 쿼리를 동시에 처리하는 방법을 생각하고 있습니다. 두 테이블의 연관관계가 전혀없어서 조인하지 않고 따로따로 쿼리해서 가져와야 하는 경우에는 어떻게 하시나요? 강의에서는 직렬로 쿼리를 수행하는데 영한님께서는 병렬로 쿼리를 수행하실때 어떻게 처리하시나요? 그냥 직렬로 쿼리를 하나요?
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
QueryDSL 강의 수강에 대한 질문입니다.
안녕하세요. 항상 좋은 강의 감사합니다. 이번에 JPA 활용 2편까지 수강을 마무리하고 직접 JPA를 활용해서 프로젝트를 만들어볼 생각인데요. 스프링 데이터 JPA의 경우는 JPA를 빠르고, 간결하게 사용할 수 있게 도와주는 용도라서 필수가 아니지만, QueryDSL은 JPA를 활용하는데 있어서 처리하기 힘든 동적쿼리를 쉽게 해결해주기 때문에 필수라고 생각했습니다. 당장 급하게 프로젝트를 만들어야하는 상황이라서 듣더라도 QueryDSL 중에서도 동적쿼리 부분만 빠르게 들어야할 상황인데요. 스프링 데이터 JPA 강의를 듣지 않더라도 QueryDSL 강의를 이해하는데 어려움없이 들을 수 있을까요?
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
OSIV off 패키지 구조
안녕하세요. 항상 좋은 강의 감사드립니다. 강의에서 실시간 요청이 많은 서비스의 경우, OSIV 옵션을 off하고 쿼리 서비스를 따로 분리하여 패키지 구조를 가져가라고 말씀해주셨습니다. 패키지 구조를 분리하는 것까지는 이해했는데, 어떤 구조로, 어떤 점을 고려해서 구조를 잡아야할지 감이 오질 않아서 혹시 참고할 수 있는 예제나 설명이 있을까하여 질문드립니다. 강의에서는 예제 설명을 위해 간단하게 서비스 패키지 내부에 쿼리 패키지를 두어 만드셨는데요. 좋은 방법은 아니라고 언급해주어 질문드립니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
OrderRepository에 @Transactional 붙여줬을 시
혼자서 코드를 짜서 하던 도중, 선생님과 ordersV3_page 부분에서 쿼리가 다르게 나가서 이것저것 확인해 본 결과, OrderRepository에 @Transactional의 차이란것을 깨달았습니다. OrderRepository에 @Transactional을 붙여주면, 배치사이즈 100을 사용해도, 아래 사진과 같이 OrderItems에는 배치사이즈가 적용되지 않고, 1개씩 총 두번 쿼리가 수행된다는 것을 알게되었습니다. @Transactional을 빼주거나 @Transactional(readOnly = true)를 해주면 OrderItem에 배치사이즈가 적용되어 한번에 여러개를 가져오는것도 확인했습니다. 왜 위와같은 현상이 발생되는 것일까요..? 아래 사진은 @Transactional을 사용 시 orderItem에 배치사이즈가 적용되지 않는 사진입니다
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
질문 하나 드립니다.
즐겁게 공부하고 있습니다. 감사합니다. hibernate.default_batch_fetch_size 100으로 설정한 후 쿼리 나가는 걸 보고 약간 의문이 드는데요, 초기 Order 를 2개 가지고 오고 순서가 1번 Order -> 1번 Order에 물려있는 1,2 번 OrderItem -> 1,2번 OrderItem에 물려있는 1,2 번 Item 2번 Order -> 2번 Order에 물려있는 3,4번 OrderItem -> 3,4번 OrderItem에 물려있는 3,4번 Item 인 것 같습니다. 하지만 쿼리 나가는 걸 보니 1번 Order에 물려있는 1,2번 OrderItem를 DB에서 꺼내올 때, 2번에 물려있는 3,4번 OrderItem도 같이 긁어 오더라구요?? Item 꺼낼 때도 1,2번 OrderItem에 물려있는 1,2번 Item 긁어 올때 3,4번도 같이 긁어오구요. JPA가 제가 2번 Order에 물려있는 3,4번 OrderItem을 긁어 올지 않올지 어떻게 판단하고, 처음에 싹다 긁어오나요??... 만약 제가 OrderId = 2 인것을 제외하는 로직을 세웠다라고 하면 이 로직전에 JPA가 일단 다 긁어 오는 것 같은데... 제 생각이 맞는지... 맞다면 JPA가 일단 그런거 모르겠고, 초장에 다 긁어 온다음에 처리를 하나요..?? 미리 감사드립니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
JPA에서 엔티티를 삭제 혹은 업데이트 할 때 리턴에 대해 질문드립니다.
안녕하세요! 엔티티를 JPA로 삭제 혹은 업데이트 처리 후에 반환형이 void 아니면 해당 엔티티의 id 값을 반환 받는데요. 혹시 삭제나 업데이트를 하는 와중에 DB커넥션 오류가 발생한다면, 개발자 입장에서 Repository에서 오류가 난 뒤 에러처리를 어떻게 할 수 있을까요? 답변 기다리겠습니다. 감사합니다!
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
QueryDsl Q파일들이 안보입니다.
여기까진 잘 되는데 generated 폴더가 비어있고 혹시나해서 QOrder를 쳐봐도 잡히는 클래스 타입이 없네요 빌드 쪽도 설정해서 해봤는데 거기도 빈 폴더만 잡힙니다. 구글링해도 확실한 해결책이 없는것 같은데 어떡하죠...
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
슬슬 이해가 되네요 ㅎㅎ
실전2 강의 처음봤을 때는 이해가 안가는 부분이 많았는데 2번 째 들어보니까 지금까진 이해가 잘되네요 ㅎㅎ 역시 복습이 답이네요!!
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
단순히 엔티티(테이블)의 저장된 값이 아닌 연관된 통계 값(?) 등을 같이 조회할 경우는 어떤 패턴을 사용하나요?
안녕하세요. 예를 들어 상품 리스트 api 를 구현한다고 했을 때, 상품별 데이터에 추가로 api를 조회하는 회원이 해당 상품을 좋아요(찜, 장바구니 담기 등) 했는지 여부, 그리고 해당 상품이 현재까지 구매된 건수(또는 구매한 회원수) 등을 같이 내려줘야한다면 보통 어떤 식으로 구현을 하시나요? 이런 값들은 기본적으로 각 엔티티(상품?)에 관계매핑이 될만한 것들은 아닌 것으로 판단되는데요, 그리고 이런 값들은 간단하게 (위의 예를 기준으로)상품 리스트를 조회할 때 한번에 같이 뽑아지기 어려운 경우가 대부분일 것 같습니다. 아직 저희는 JPA 를 실무에 도입하기 전이기도 한데, 보통 이런 경우 상품 정보 리스트를 뽑아오고 해당 상품 번호 리스트로 해당 부가적은 데이터를 한번 더 조회한 후, 두 리스트 값으로 내려줄 값을 한번더 가공하는 방식을 사용합니다. 물론 한방 쿼리로 다 가져올 수 있는 경우는 (아직 JPA 를 도입하기 전이라) 하나의 쿼리로 만들어 내려주기도 하구요. 보통 JPA를 사용하는 실무에서 이런 케이스는 어떻게 구현을 하시는지요?
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
엔티티를 컨트롤러 메서드 안에서 생성해서 쓰는 건 괜찮나여??
안녕하세요 영한님! 강의 정말 잘 듣고 있습니다. 강의를 보면서 궁금함 점이 생겨 질문드립니다. 질문1. V2 메서드 만들때 Member 객체에 값을 받아서 사용하셨는데 컨트롤러 메서드 안에서는 엔티티를 사용해도 상관없는건가요? 질문2. Member 객체를 사용하는 대신 service에 DTO를 파라미터로 받는 메서드를 추가해서 사용해도 되는지 궁금합니다.
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Collectors.groupingBy와 mapping할 때 static안하고 사용 시
Collectors를 static하면 오류가 안나고 static 없이 사용하면 오류가 나는데 무슨 차이가 있을까요 ? static import없이 groupingBy와 mapping 동시 사용 (o.getOrderId(), o.getName() 같이 객체 필드를 가져오는 곳에서 컴파일 오류남) Map<OrderQueryDto, List<OrderFlatDto>> collect = orderAllByDto_flat.stream() .collect(Collectors.groupingBy(o -> new OrderQueryDto(o.getOrderId(), o.getName(), o.getOrderStatus(), o.getAddress()), Collectors.mapping(o -> new OrderItemQueryDto(o.getOrderId(), o.getItemName(), o.getCount(), o.getPrice()), toList())); static import시 (컴파일 안남) List<OrderFlatDto> orderAllByDto_flat = orderQueryRepository.findAllByDto_flat();Map<OrderQueryDto, List<OrderFlatDto>> collect = orderAllByDto_flat.stream() .collect(groupingBy(o -> new OrderQueryDto(o.getOrderId(), o.getName(), o.getOrderStatus(), o.getAddress()), mapping(o -> new OrderItemQueryDto(o.getOrderId(), o.getItemName(), o.getCount(), o.getPrice()), toList())); 제가 static import에 관해서 모르는 부분이 있는 걸까요 ? :(
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
in :orderids 일 때 DB 쿼리에 대하여 (사소함)
사소한 것 같은데 호옥시나 해서 질문합니다. List<OrderQueryDto> orderDtos = findOrderQueryDtos(); List<Long> orderIds = orderDtos.stream().map(o -> o.getOrderId()).collect(Collectors.toList()); List<OrderItemQueryDto> orderItemDtos = em.createQuery("select new jpabook.jpashop.repository.order.query" + ".OrderItemQueryDto(oi.order.id, i.name, oi.count, oi.orderPrice)" + " from OrderItem oi join oi.item i where oi.order.id in :orderIds", OrderItemQueryDto.class).setParameter("orderIds", orderIds).getResultList(); 일 때, orderIds = [4, 11] 인데 이걸 in :orderIds에 넣으면 [4, 11]이 아니라 내부에서 자동으로 (4, 11)로 괄호가 바뀌어서 DB에 날라가는 거 맞나요 ? List 구조를 보고, 쿼리를 보면 그런 것 같은데 혹시나 혹시나 해서 사소하게 물어봅니다 :]