묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
결과 쿼리 개수가 맞지 않아서 문의 드립니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용][간단한 주문 조회 V3: 엔티티를 DTO로 변환 -패치 조인 최적화] 강의에서 5분 50초 쯤에 v2를 돌려봤을 때, 강사님은 쿼리가 5번 나오는데,저는 계속 7번이 나오더라구요...order가 처음에 주문 2개를 만들어서 이미 영속성 상태라 그 다음에는 1차 캐시에서 가져오는 것으로 보여 쿼리는 생성이 안되어야 한다고 생각이 드는데, 왜 계속 order 쿼리가 2번 더 나오는 걸까요...? [Query]2023-10-25T21:54:33.448+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selecto1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.statusfromorders o1_0joinmember m1_0on m1_0.member_id=o1_0.member_idfetchfirst ? rows only2023-10-25T21:54:33.449+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473449 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id fetch first ? rows onlyselect o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id fetch first 1000 rows only;2023-10-25T21:54:33.450+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selectm1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.namefrommember m1_0wherem1_0.member_id=?2023-10-25T21:54:33.451+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473451 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=1;2023-10-25T21:54:33.451+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selectd1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.statusfromdelivery d1_0whered1_0.delivery_id=?2023-10-25T21:54:33.451+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473451 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=1;2023-10-25T21:54:33.452+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selecto1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.statusfromorders o1_0whereo1_0.deliver_id=?2023-10-25T21:54:33.452+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473452 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=?select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=1;2023-10-25T21:54:33.453+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selectm1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.namefrommember m1_0wherem1_0.member_id=?2023-10-25T21:54:33.453+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473453 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=2;2023-10-25T21:54:33.453+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selectd1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.statusfromdelivery d1_0whered1_0.delivery_id=?2023-10-25T21:54:33.454+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473454 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=2;2023-10-25T21:54:33.454+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :selecto1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.statusfromorders o1_0whereo1_0.deliver_id=?2023-10-25T21:54:33.454+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473454 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=?select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=2; [OrderSimpleApiController]package jpabook.jpashop2.api;import jpabook.jpashop2.Repository.OrderRepository;import jpabook.jpashop2.Repository.OrderSearch;import jpabook.jpashop2.domain.Address;import jpabook.jpashop2.domain.Order;import jpabook.jpashop2.domain.OrderStatus;import lombok.Data;import lombok.RequiredArgsConstructor;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;import java.util.List;import java.util.stream.Collectors;/*** X To One (컬렉션 X)* Order* Order -> Member* Order -> Delivery*/@RestController@RequiredArgsConstructorpublic class OrderSimpleApiController {private final OrderRepository orderRepository;@GetMapping("/api/v1/simple-orders")public List<Order> ordersV1(){List<Order> all = orderRepository.findAllByString(new OrderSearch());for (Order order : all) {order.getMember().getName(); // Lazy 강제 초기화order.getDelivery().getAddress(); // Lazy 강제 초기화}return all;}@GetMapping("/api/v2/simple-orders")public List<SimpleOrderDto> ordersV2(){// Order 2개List<Order> orders = orderRepository.findAllByString(new OrderSearch());List<SimpleOrderDto> result = orders.stream().map(o -> new SimpleOrderDto(o)) // map : a -> b로 치환.collect(Collectors.toList());return result;}@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;}@Datastatic class SimpleOrderDto{ // API 명세서private Long orderId;private String name;private LocalDateTime orderDate;private OrderStatus orderStatus;private Address address;public SimpleOrderDto(Order order) {orderId = order.getId();name = order.getMember().getName();orderDate = order.getOrderDate();orderStatus = order.getStatus();address = order.getDelivery().getAddress();}}} [OrderRepository]... 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();}
-
미해결
스프링 사용 중 생기는 오류
안녕하세요spring tools4를 설치하였고 돌아가는지 확인하고 싶어 확인하는 도중에 오류가 걸려서 글 올립니다.java는 11로 사용하였고demo1는 local로 실행했을 때 Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/SpringApplication has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0오류가 떠서 java버전이 다르다는 것을 알기는 알아냈지만 인터넷으로 검색한 방법을 다 써봐도 해결이 안됐습니다.사용한 방법은 build path에서 jre system library로 해보았고 installed jres도 제대로 해두었습니다.compiler에도 11로 표시하였는데 혹시 다른 추가적이 방법이 있을까요
-
해결됨스프링 핵심 원리 - 기본편
프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]학습 자료의 생성자 주입을 선택하라는 내용에서 '누락' 설명하는 부분에 써진 내용을 보고 질문 드립니다. 아래는 학습 자료에 있는 내용 복붙한 거입니다.프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우에 다음과 같이 수정자 의존 관계인 경우 @Autowired가 프레임워크 안에서 동작할 때는 의존 관계가 없으면 오류가 발생하지만, 지금은 프레임워크 없이 순수한 자바 코드로만 단위 테스트를 수행하고 있다. 이렇게 테스트를 수행하면 실행은 된다. 그런데 막상 실행 결과는 NPE(Null Point Exception)이 발생하는데, memberRepository, discountPolicy 모두 의존 관계 주입이 누락되었기 때문이다 여기서 말하고자 하는 바는"프레임워크 없이 순수한 자바 코드를 단위 테스트 하는 경우엔 수정자 주입 방법의 경우 문제가 생긴다."가 아니라"수정자 주입을 하면 만일 개발자의 실수로 뭔가를 누락할 경우 발견하기 어려울 수 있다. 그러므로 수정자 주입을 안 하는 게 좋다."라는 게 맞나요? 즉 수정자 주입으로 해도 테스트할 수는 있지만 여러모로를 따졌을 때 생성자 주입이 실수할 확률이 적어서 낫기 때문인지 궁금합니다. 단위 테스트할 때 set 메서드를 직접 호출하면 수정자 주입의 경우에도 자바로 단위 테스트 할 수는 있는 거죠? 제가 코드를 짰을 땐 되는 것 같은데 제가 제대로 코드를 짠 게 아닐 수 있어서 검증이 제대로 된 건지 모르겠어서 질문드립니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
ProductNumberFactory 클래스는 어떤 Layer 객체로 봐야 할까요?
안녕하세요! 먼저 항상 좋은 강의 감사드립니다! 저도 작은 경험 이지만 개발을 하면서 서비스 단의 로직을 분리 (강의에서 말씀 해주신 것 처럼 책임을 분리할 정도)해야 하는 상황인 경우, 이렇게 하는게 맞는지는 모르겠으나, Point1. ServiceUtil 클래스를 정의하여 컴포넌트로 주입받아 사용하거나 (실무에선 이렇게 사용)Point2. 학습시에는 Facade 패턴을 이용하여 서로 다른 서비스들의 상위 퍼사드 객체를 만들어서 사용한 적이 있습니다.(물론 퍼사드 패턴의 경우, 두 로직이 완전히 다른 맥락인 경우에 사용하는 것 같습니다.. 강의 예제와 같이 결합도가 높은 경우가 아니라..)그런데, 강의에서는 Factory 객체를 만들어서 (마치 제가 ServiceUtil을 만들어서 사용하는 것 처럼 - 사실 이름만 다르지 같습니다)사용하시는 모습을 보여주셨는데, Q1. 강사님께서는 실무에서 서비스의 책임을 분리할 때 주로 이런식으로 Factory 클래스를 분리하여 사용하시는지 궁금하고, Q2.그렇게 Factory 클래스로 책임을 분리했을 때, 이 Factory 클래스는 Controller / Service/ Repository 그 어느것도 아니게 되는데, Spring WEB mvc 레이어 아키텍쳐 상으로 어떤 Layer의 어떤 입장의 객체로 인지하고 사용해야 하는지 여쭙고 싶습니다. 감사합니다.
-
미해결실전! 스프링 데이터 JPA
실무에서 @DynamicInsert, @DynamicUpdate 사용하나요?
안녕하세요!좋은 강의 잘 들었습니다! 실무에서 JPA를 사용하면서 궁금한점이 있어서요실무에서는 @DynamicInsert, @DynamicUpdate 사용하고 있는데영한님은 한번도 안쓰시더라구요..!실무에서는 어떻게 사용하시는지 궁금합니다!@DynamicInsert, @DynamicUpdate 사용하지 않으면 어떻게 사용하는지도 궁금합니다.
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
EntityManager를 쓰는데, DB가 다르면 EntityManager도 2개 주입받아야 해요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]예를 들면 좀 회사의 기존 서비스에서 아예 새로운 서비스말고 기존의 서비스를 활용해서 뭔가 고객에게 제공해 주고 싶다, 하면 기존DB랑 새로 추가 해야 할 DB랑 다를 수 있잖아요.근데 EntityManager는 우리 눈에는 안보이지만, 자동으로 DataSource 주입 받잖아요.DataSource가 제가 기억하기로 말 그대로 데이터의 근원, h2 이런 것 들에 대한 연결할 수 있는 정보? 들을 얻어오는 걸로 기억을 해서, DB가 다르면 저것도 다를 수 있잖아요. 또 DB의 계정마다도 다를 것 같고.. 그러면 EntityManager가 2개 생기나요? 이번엔 같은 DB에 테이블만 다른거니 JPA 내부적으로 sql만 좀 다르게 짤거니까 상관 없어 보이지만..
-
미해결스프링부트 시큐리티 & JWT 강의
Facebook 로그인 버튼만든 후 error(Sorry...) 발생시
인증 및 계정 만들기 > 수정 에서 Email 권한 추가해주어야 오류 안나네요.
-
미해결
sprign webflux와 main 쓰레드 수
제가spring webflux를 공부하다가 궁금한게 있어서 이렇게 질문 남깁니다.webflux는 비동기 프로그래밍을 지원하기 때문에 적은 쓰레드 수로도 대량의 트래픽을 처리할 수 있다고 알고 있는데요. [실제로 사용자 요청을 받는 main 쓰레드는 한 개만 생성되는지 궁금합니다.]webflux는 블로그를 보다가 default값으로 core 당 한개의 쓰레드가 생성한다고 본거 같은데.. 이게 main 쓰레드는 한개 인데 sub 쓰레드(block 상태 풀린 쓰레드 요청 처리 용, event loop 처리 용 등)들이 core 갯수까지 추가적으로 생성된다는건지(main + sub == core수), 아니면 main 쓰레드가 실제로 코어 수만큼 생성이 된다는 의미인지 잘 모르겠네요..마지막으로, 후자가 맞다면 webflux는 소수의 main 쓰레드로 멀티 쓰레딩 지원과 비동기 프로그래밍을 지원한다고 보면되는걸까요?
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
31:04 부분 "select o from Order o" 만 했을 경우 결과값
2023-10-09T19:14:55.542+09:00 INFO 2455 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2023-10-09T19:14:55.542+09:00 INFO 2455 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2023-10-09T19:14:55.542+09:00 INFO 2455 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms 2023-10-09T19:14:55.660+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 offset ? rows fetch first ? rows only 2023-10-09T19:14:55.662+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495662 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 offset ? rows fetch first ? rows only select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 offset 0 rows fetch first 100 rows only; 2023-10-09T19:14:55.668+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where array_contains(?,m1_0.member_id) 2023-10-09T19:14:55.672+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495672 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where array_contains(?,m1_0.member_id) select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where array_contains('ar0: ARRAY [CAST(1 AS BIGINT), CAST(2 AS BIGINT)]',m1_0.member_id); 2023-10-09T19:14:55.674+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select d1_0.id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where array_contains(?,d1_0.id) 2023-10-09T19:14:55.674+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495674 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select d1_0.id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where array_contains(?,d1_0.id) select d1_0.id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where array_contains('ar1: ARRAY [CAST(1 AS BIGINT), CAST(2 AS BIGINT)]',d1_0.id); 2023-10-09T19:14:55.676+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-10-09T19:14:55.677+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495677 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=? select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=1; 2023-10-09T19:14:55.677+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-10-09T19:14:55.678+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495678 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=? select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=2; 2023-10-09T19:14:55.680+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.order_item_id, o1_0.count, o1_0.item_id, o1_0.order_price from order_item o1_0 where array_contains(?,o1_0.order_id) 2023-10-09T19:14:55.686+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495686 | took 5ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.order_item_id,o1_0.count,o1_0.item_id,o1_0.order_price from order_item o1_0 where array_contains(?,o1_0.order_id) select o1_0.order_id,o1_0.order_item_id,o1_0.count,o1_0.item_id,o1_0.order_price from order_item o1_0 where array_contains('ar2: ARRAY [CAST(1 AS BIGINT), CAST(2 AS BIGINT), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL]',o1_0.order_id); 2023-10-09T19:14:55.687+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select i1_0.item_id, i1_0.dtype, i1_0.name, i1_0.price, i1_0.stock_quantity, i1_0.artist, i1_0.etc, i1_0.author, i1_0.isbn, i1_0.actor, i1_0.director from item i1_0 where array_contains(?,i1_0.item_id) 2023-10-09T19:14:55.688+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495688 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select i1_0.item_id,i1_0.dtype,i1_0.name,i1_0.price,i1_0.stock_quantity,i1_0.artist,i1_0.etc,i1_0.author,i1_0.isbn,i1_0.actor,i1_0.director from item i1_0 where array_contains(?,i1_0.item_id) select i1_0.item_id,i1_0.dtype,i1_0.name,i1_0.price,i1_0.stock_quantity,i1_0.artist,i1_0.etc,i1_0.author,i1_0.isbn,i1_0.actor,i1_0.director from item i1_0 where array_contains('ar3: ARRAY [CAST(1 AS BIGINT), CAST(2 AS BIGINT), CAST(3 AS BIGINT), CAST(4 AS BIGINT)]',i1_0.item_id); 이 결과값에서 강의랑 다른 부분이 있어서 질문 드립니다하이버네이트 6.2 라서 array_contains 인거 아는데 아래 부분이 이해가 안됩니다. select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-10-09T19:14:55.677+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495677 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=? select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=1; 2023-10-09T19:14:55.677+09:00 DEBUG 2455 --- [nio-8080-exec-1] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-10-09T19:14:55.678+09:00 INFO 2455 --- [nio-8080-exec-1] p6spy : #1696846495678 | took 0ms | statement | connection 7| url jdbc:h2:tcp://localhost/~/jpanew select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=? select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=2;orders 를 처음에 조회하고 나서 또 추가적으로 o1_0.delivery_id=?이걸로 조회하는 결과가 왜 생기는걸까요?..(배치사이즈도 강의랑 똑같이 100입니다) OrderApiController.java@GetMapping("/api/v3.1/orders") public List<OrderDto> ordersV3_page(@RequestParam(value ="offset",defaultValue = "0") int offset, @RequestParam(value ="limit",defaultValue = "100") int limit) { List<Order> orders = orderRepository.findAllWithMemberDelivery(offset,limit); List<OrderDto> result = orders.stream() .map(o -> new OrderDto(o)) .collect(Collectors.toList()); return result; } OrderRepository.java public List<Order> findAllWithMemberDelivery(int offset, int limit) { return em.createQuery( "select o from Order o" , Order.class ).setFirstResult(offset) .setMaxResults(limit) .getResultList(); }이렇게 바꾸고 난 이후에 일어난 결과입니당..강의랑 In말고도 추가적으로 다른 부분이 있어서 질문드립니다일단 제 스프링부트 버전은 3.1.3 입니다.
-
해결됨
스프링 dependency 추가 어떻게 해요?
aspose엑셀 Dependency 추가가 잘안되네요..
-
미해결Practical Testing: 실용적인 테스트 가이드
Controller와 Service간의 requestDto를 구분하는 측면
충분히 공감가고 이해되는 내용입니다! 좋은 내용 설명해주셔서 감사합니다!그렇다면 responseDto도 순수 서비스 응답과 ,각 컨트롤러 별 응답으로 구분하는게 좋을까요?
-
해결됨스프링 핵심 원리 - 기본편
안녕하세요 제가 프로토타입 스코프를 싱글톤 빈과 사용시 발생하는 문제점을 정리했는데 맞게 정리를 한건지 궁금해서 질문을 합니다.
[질문 내용]프로토타입 빈은 스프링 컨테이너에 요청시 새로 생성하고 반환한다. 이때 싱글톤 빈과 함께 사용이 되면 싱글톤 빈은 한번만 생성이 되므로 싱글톤 빈이 자동으로 의존관계 주입을 하게 되면 싱글톤 빈이 프로토타입 빈 한개를 계속 사용하게 된다 왜냐면 싱글톤 빈에서 의존관계 주입은 한번만 발생하기 때문이다. 따라서 싱글톤빈이 매번 새로운 프로토타입 빈을 사용하는게 아니라 의존관계를 주입할때 가져온 프로토타입 빈을 싱글톤 빈의 생명주기에 맞춰서 사용하게 된다.다만 clientA, clientB 여러 싱글톤 빈들이 프로토타입 빈을 주입 받을때는 주입 받는 시점에 각각 새로운 프로토타입 빈이 생성되서 주입을 받으므로 각 싱글톤 빈들이 가지는 프로토타입 빈은 다르다. 하지만 결국에는 각각의 싱글톤 빈들이 위와 같은 문제를 가지게 된다.감사합니다.
-
미해결Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
버퍼가 비워지는 시점
안녕하세요. Backpressure의 Drop 전략에서 버퍼가 비워질 때까지 Emit된 데이터가 Drop이 된다는 것은 이해했습니다.그런데 1번 데이터가 subscriber에게 전달되어서 처리가 되면 버퍼에 자리가 한 자리 비게 되는데 왜 데이터가 계속 Drop이 되는건가요? (코드 실습에서 onNext()함수가 호출이 되어도 255,256,257 ~ 1024까지 모두 드랍됨)| 1, 2 | <-------- 3 듣랍| 2, |. <-------- 4 드랍 (여기서 왜 4번 데이터는 안들어가나요?)| 5, 6 | Buffer DROP-LATEST를 보면 | 1, 2 | <---- 3들어오는 중 버퍼 가득 차서 drop | 2, 4 | <------ 1번이 버퍼에서 나가고 한 자리가 비어서 4번이 들어와짐 이런식으로 동작을 하는데 Drop은 이렇게 동작하지 않는 것 같아 버퍼가 어떻게 동작하는지 궁금하여 질문드립니다.
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
Controller에서 BindingResult값을 유지한채로 @ExceptionHandler를 활용한 사용자 정의 예외를 처리하는법이 궁금합니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Spring data jpa 를 활용하여 지금까지 배운 내용들을 총 합한 프로젝트를 만들어 보고 있는데 한가지 궁금증이 생겨 질문 드립니다. @ExceptionHandler을 사용하여 사용자정의 예외를 만들어 아이디 중복 예외를 처리하고싶은데 예외를 처리하는 과정에서 아이디가 중복일시 Controller의 BindingResult를 활용하여 아이디가 중복이면 View에 아이디가 중복이라는 정보를 표현하고싶어서 프로젝트를 코딩중에 Controller 부분에서 service단에서 throw한 사용자 정의 예외를 처리하려 하는데 try catch로 예외를 처리하는 순간 @ExceptionHandler를 사용하지 못하고 그렇다고 다시 예외를 던지자니 @ExceptionHandler에서 View에 관련된 Binding result의 값이나 ModelAttribute의 값을 보존해지 못하여 처리가 불가합니다. 이럴때 제일 좋은 방법이 무엇인지 알고싶습니다. Controller 코드입니다.@Controller @RequiredArgsConstructor @RequestMapping("/users") public class UserController { private final LoginService loginService; @GetMapping("/add") public String addForm(@ModelAttribute("userDto") UserDto userDto) { return "user/addUserForm"; } @PostMapping("/add") public String save(@Valid @ModelAttribute UserDto userDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "user/addUserForm"; } // if (loginService.signUpIdExists(userDto.getLoginId()) == false){ // bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); // return "user/addUserForm"; // } try { loginService.signUp(userDto); return "redirect:/"; } catch (UserIdExistsException e) { bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); return "user/addUserForm"; } } } Service 코드입니다.@Slf4j @Service @RequiredArgsConstructor public class LoginService { private final UserRepository userRepository; public User login(String loginId, String password) { return userRepository.findByLoginId(loginId).filter(m -> m.getPassword().equals(password)) .orElse(null); } public void signUp(UserDto userDto) { // if(signUpIdExists(userDto.getLoginId()) == false){ // throw new UserIdExistsException("이미 존재하는 아이디입니다."); // } try { Address address = new Address(userDto.getAddressDto().getZipcode(), userDto.getAddressDto().getStreetAdr(), userDto.getAddressDto().getDetailAdr()); User regisUser = new User(userDto.getLoginId(), userDto.getLoginName(), userDto.getPassword(), address); userRepository.save(regisUser); } catch (DataIntegrityViolationException e) { throw new UserIdExistsException("이미 존재하는 아이디입니다."); } } private boolean signUpIdExists(String loginId) { return userRepository.findByLoginId(loginId).isEmpty(); } } @ControllerAdvice 코드입니다.@Slf4j @ControllerAdvice public class ExceptionAdvice { @ExceptionHandler(UserIdExistsException.class) public ModelAndView userIdExHandler(UserIdExistsException e) { log.error("[userIdExistsException] ex", e); return new ModelAndView(); } } UserIdExistsException 코드입니다.public class UserIdExistsException extends RuntimeException{ public UserIdExistsException() { } public UserIdExistsException(String message) { super(message); } } 위 코드는 동작은 확인했지만 사실상 try catch 로 예외를 잡아버려서 @ExceptionHandler가 동작하지 않는 상태입니다. Entity의 아이디값에 unique 옵션을 걸어두어 아이디 중복이 일어날시 DataIntegrityViolationException에러가 일어납니다.추가로 궁금한것예외가 사실상 repository에서 터지는데 인터페이스에는 try catch가 권장되지 않는것으로 알고 통상 Service에서 에러를 처리하는것으로 알아 이렇게 코딩하였는데 이게 올바른건지 모르겠습니다. 예외를 발생시키는 지점을 repository로 옮기는것이 맞나요? Spring data jpa 는 알아서 Spring에 종속된 에러를 출력하는것으로 알고있는데 DataIntegrityViolationException에 속한 예외 두가지를 다른방법으로 처리하고싶으면 ErrorCode를 분석해 If문 으로 사용자 정의 예외를 만들어서 처리해야하나요? bindingresult를 사용하기 위해 어쩔수없이 예외를 throw하였더니 controller까지 예외가 전파되서 코드가 지저분해졌습니다. 이렇게 View에 특정한 값을 보내주어야할때 Controller에 예외를 throw 하지 않고 해결할수있는 좋은 방법이 있나요? 질문이 길고 지저분해서 죄송합니다. 나름 열심히 알아보고 코딩해보아도 잘 모르겠어서 질문남깁니다. 감사합니다.
-
미해결스프링 핵심 원리 - 고급편
실행순서
안녕하세요실행 순서: @Around , @Before , @After , @AfterReturning , @AfterThrowing 라고 적어주셨는데 @After 이게 왜3 번째로 실행된다고 표현 해주신게 이해가 조금 안갑니다. 실제로는 @AfterReturnin 다음에 실행되는거 아닌가요 ?
-
미해결스프링 부트 - 핵심 원리와 활용
디스패처 서블릿과 스프링 컨테이너 연결 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]강의 내용대로 스프링 MVC 디스패처 서블릿을 생성한 후 스프링 컨테이너를 연결하려고 보니까 다음과 같이 오류가 뜹니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
basic/items.html 입력시에만 화이트 라베 오류가 발생합니다. 제발 도와주세요 ㅠㅠ
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.items.html 수정 전 코드 입력시에는 웹 페이지가 잘 작동하는데<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link href="../css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <style> .container { max-width: 560px; } </style> </head> <body> <div class="container"> <div class="py-5 text-center"> <h2>상품 상세</h2> </div> <div> <label for="itemId">상품 ID</label> <input type="text" id="itemId" name="itemId" class="form-control" value="1" th:value="${item.id}" readonly> </div> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}" readonly> </div> <div> <label for="price">가격</label> <input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}" readonly> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}" readonly> </div> <hr class="my-4"> <div class="row"> <div class="col"> <button class="w-100 btn btn-primary btn-lg" onclick="location.href='editForm.html'" th:onclick="|location.href='@{/basic/items/{itemId}/ edit(itemId=${item.id})}'|" type="button">상품 수정</button> </div> <div class="col"> <button class="w-100 btn btn-secondary btn-lg" onclick="location.href='items.html'" th:onclick="|location.href='@{/basic/items}'|" type="button">목록으로</button> </div> </div> </div> <!-- /container --> </body> </html> 수정 후 코드를 복붙 후에 웹 페이지에 입력하면 화이트 라벨 페이지가 응답합니다...뭐가 문제인지 모르겠습니다.. 도와주세요
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
여러 패키지들 does not exist 오류
안녕하세요 김영한님! 강의 아주 잘 듣고있습니다!! 현재 김영한님 첫번째 강의를 다 듣고 저 혼자 만들어보고 싶은게 생겨서 만드는중인데요 현재 제가 군대에 있어서 사지방에서 코딩을 하느라 인텔리제이를 사용하지 못하고 깃허브에서 제공하는 codespaces와 gitpod을 사용하여 vscode 환경에서 코딩하는 중입니다. 근데 jpa의 JpaRepository나 lombok 혹은org.springframework.boot.autoconfigure.SpringBootApplication 이런 패키지들이 계속 does not exist라고 뜹니다. 김영한님꺼 따라할때는 잘 됐는데 이제 제가 혼자서 만들고 싶은거 만드려니 확실하지도 않고 실행도 잘 안돼서 패키지를 못읽는건지도 잘 모르겠습니다. 현재 build.gradle에 의존성도 다 넣어있고 vscode의 패키지 설치에도 java extention pack, lombok, spring extention pack또 다 깔았습니다. 당연 재설치도 해보았구요! 구글링을 지금 며칠째 하고있는데 도저히 안되서 여기에 질문 올려봅니다...springboot version : 3.1.3jdk version : 17
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
jdbc:h2:tcp://localhost/~/test로 연결시 오류가 발생합니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]여기에 질문 내용을 남겨주세요.최초로 jdbc:h2:~/test로 연결을 실행 한 뒤~/test.mv.db 파일 생성을 확인하였습니다.그러고 영한님께서 말씀해주신 대로jdbc:h2:tcp://localhost/~/test로 연결했더니 다음과 같은 오류가 발생하네요.. 해결방안 답변해주시면 감사하겠습니다.참고로 h2 버전은 강의와 같은 버전을 사용하였습니다. +) 추가로 삭제 후 동일버전, 하위버전으로 재설치도 해보았는데 여전히 같은 오류가 발생합니다.
-
미해결스프링 부트 - 핵심 원리와 활용
EmbedTomcatServletMain 실행 시 발생하는 오류
complete 코드를 사용해도 다음과 같은 오류가 나옵니다Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.webresources.StandardRoot@35cabb2a]