학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 입문이나 기본편에서는 인터페이스를 만들어서 확장을 염두에 두었는데 JPA는 인터페이스 기반 설계를 못하는 건가요?? 아니면 일부로 안 하신건가여
학습중 궁금한 것은 언제든 문의 하세요. 질문을 최대한 자세히 남겨주시면 반드시 답변 드리도록 하겠습니다. 추가로 알고 싶은 내용도 요청해주시면 강의 자료를 업데이트 해서 제공할 예정입니다. 선생님 좋은 강의 감사합니다. 강의 재밌게 듣고 있습니다. 브로드캐스트활용해서 채팅(실시간 알림)기능 구현 강의 듣던 중 궁금한게 생겼는데요 그 전 강의에서 8080 8081 두개 서버 띄어놓고 라운드로빈으로 분배되는 것 설명하셨을 때 처럼 두개 띄어놓고 8080 8081 각각의 웹소켓으로 메세지 전송했는데 각각의 서버 별로 별도로 브로드캐스팅이 되는 것 같더라고요. 전체로 브로드캐스팅 하려면 보통 어떤 식으로 구현하나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요 mybatis를 체득하고 싶어서 게시판 프로젝트를 한번 해보려고 했는데 잘 안되네요 https://drive.google.com/file/d/1ku2NtUWjeSi1OJ2Z7SLsuqqG7Y471BHv/view?usp=sharing 파일은 여기있습니다. 강의보고 따라하긴 했는데 제가 제대로 이해를 못한건가 싶습니다 제가 생각하는 (공부해서 알게 된) 순서는 이렇습니다 client의 request요청 - JSON배열로 { "id": 1, "title": "게시글 제목", "content": "게시글 내용" } 이렇게 온다고 가정 Controller에서 request를 @RequestBody 받고 service로 전송 Service에서 dto를 param으로 변환하고 param을 mapper 인터페이스의 메서드로 감싸기 Mapper 인터페이스에서 전달받은 메서드 이름과 id가 같은 mapper.xml로 보내서 CRUD 실행 service Mapper.saveBoard(param)으로 → client에 넘겨줄 responseDto로 param을 보냄 create table member( id bigint auto_increment primary key, board_writer varchar(20) not null, board_passwd varchar(20) not null ); create table board( id bigint auto_increment primary key, writer_id bigint not null, title varchar(50) not null, board_contents text not null, board_count int default 0, created_at timestamp default current_timestamp, constraint fk_board foreign key(writer_id) references member(id) on delete cascade ); 테이블은 이렇고 클라이언트 실행하면 오류가 납니다; org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): Jay.Board.repository.mybatis.BoardMapper.saveBoard at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:229) ~[mybatis-3.5.14.jar:3.5.14] at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53) ~[mybatis-3.5.14.jar:3.5.14] at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:96) ~[mybatis-3.5.14.jar:3.5.14] at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na] at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:36) ~[mybatis-3.5.14.jar:3.5.14] at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:94) ~[mybatis-3.5.14.jar:3.5.14] at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) ~[mybatis-3.5.14.jar:3.5.14] at jdk.proxy2/jdk.proxy2.$Proxy63.saveBoard(Unknown Source) ~[na:na] at Jay.Board.service.BoardService.saveBoard(BoardService.java:27) ~[main/:na] at Jay.Board.controller.HomeController.saveBoard(HomeController.java:37) ~[main/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:257) ~[spring-web-6.2.2.jar:6.2.2] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.2.2.jar:6.2.2] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.2.jar:6.2.2] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.2.jar:6.2.2] ..... 이 이상은 제가 모르겠습니다…. mapper.xml이 반환되지 않는게 문제 같은데 어느부분이 문제가 되서 이러는지 도통 알 수 없네요.. 오늘 이것만 6시간째 붙잡고 있습니다.. 프로그램 흐름의 순서와 그 각각 하는 일들이 어떤 일들이 펼쳐지는지를 이해하고 코딩을 하고싶습니다…
학습중 궁금한 것은 언제든 문의 하세요. 질문을 최대한 자세히 남겨주시면 반드시 답변 드리도록 하겠습니다. 추가로 알고 싶은 내용도 요청해주시면 강의 자료를 업데이트 해서 제공할 예정입니다. 첫 pdf 에서 docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 이부분 뒤에 짤렸고 짤린 부분 다른 파일도 더 있는 것 같아요
안녕하세요, 먼저 소중한 강의 만들어주셔서 너무 감사드립니다! 🙏🏻 댓글 목록 조회 쿼리에서 궁금한 점이 있어 질문드립니다. ( 댓글 최대 2 depth - 목록 API 설계 7:19 부분 ) 질문 "튜플 비교 (a, b) > (x, y) 를 사용하면 인덱스 풀 스캔이 발생하여 성능이 매우 떨어지는데, 명시적 조건 a > x OR (a = x AND b > y) 으로 분리하면 인덱스 레인지 스캔이 발생하여 쿼리 성능이 매우 빨라지는데 왜 그런 것일지 모르겠습니다.." 질문 상세 테스트 환경: comment 에 약 8백만건의 테스트 데이터 삽입 mysql base image: mysql:8.0.38 comment table ddl -- auto-generated definition create table comment ( comment_id bigint not null primary key, content varchar(3000) not null, article_id bigint not null, parent_comment_id bigint not null, writer_id bigint not null, is_deleted tinyint(1) not null, created_at datetime not null ); create index idx_article_id_parent_comment_id_comment_id on comment (article_id, parent_comment_id, comment_id); 문제가 되는 테스트 케이스 (1: slow, 2: fast) case 1. tuple comparision (slow) explain analyze select comment.comment_id, comment.parent_comment_id, comment.content, comment.article_id, comment.writer_id, comment.content, comment.is_deleted, comment.created_at from comment where article_id = 1 and (parent_comment_id, comment_id) > (142539921307124354, 142539921307124350) order by parent_comment_id, comment_id limit 30; -- -> Limit: 30 row(s) (cost=542979 rows=30) (actual time=8620..8620 rows=30 loops=1) -> Filter: ((`comment`.comment_id,`comment`.parent_comment_id) > (142539921307124354,142539921307124350)) (cost=542979 rows=4.01e+6) (actual time=8620..8620 rows=30 loops=1) -> Index lookup on comment using idx_article_id_parent_comment_id_comment_id (article_id=1) (cost=542979 rows=4.01e+6) (actual time=1.83..8251 rows=8e+6 loops=1) case 2. fast explain analyze select comment.comment_id, comment.parent_comment_id, comment.content, comment.article_id, comment.writer_id, comment.content, comment.is_deleted, comment.created_at from comment where article_id = 1 and ( parent_comment_id > 142539921307124354 or (parent_comment_id = 142539921307124354 and comment_id > 142539921307124350) ) order by parent_comment_id, comment_id limit 30; -- -> Limit: 30 row(s) (cost=416 rows=30) (actual time=0.252..0.727 rows=30 loops=1) -> Index range scan on comment using idx_article_id_parent_comment_id_comment_id over (article_id = 1 AND parent_comment_id = 142539921307124354 AND 142539921307124350 < comment_id) OR (article_id = 1 AND 142539921307124354 < parent_comment_id), with index condition: ((`comment`.article_id = 1) and ((`comment`.parent_comment_id > 142539921307124354) or ((`comment`.parent_comment_id = 142539921307124354) and (`comment`.comment_id > 142539921307124350)))) (cost=416 rows=358) (actual time=0.232..0.705 rows=30 loops=1) 튜플 비교를 사용한 1번 쿼리에서는 index full scan 이 발생하여 ( 8백만개의 row 를 모두 스캔 ) 8초의 안좋은 쿼리 성능이 나타난 것으로 판단했습니다. 반면 튜플 비교를 명시적 조건으로 분리한 2번 쿼리에서는, ( a > X OR (a = X AND b > Y) )) index range scan 을 통해 0.7초 이하의 빠른 쿼리 성능이 나타난 것 같아요. 요약 튜플 비교 (a, b) > (x, y) 를 사용한 1번 쿼리에서 MySQL 옵티마이저는 왜 풀 인덱스 스캔을 선택하는 것인지, 튜플 비교가 인덱스 레인지 스캔으로 최적화되지 않는 이유가 무엇인지 원인을 찾고 있는데 잘 모르겠네요.. 힌트를 받을 수 있을까요? 새해복 많이 받으세요!
package enumeration.ex2; public class ClassGrade { public static final ClassGrade BASIC = new ClassGrade(); public static final ClassGrade GOLD = new ClassGrade(); public static final ClassGrade DIAMOND = new ClassGrade(); } => public static final ClassGrade BASIC; public static final ClassGrade GOLD ; public static final ClassGrade DIAMOND ; 이로면 안되나여?new를 왜햇는지 모르겟어요
package enumeration.ex1; public class DiscountService { public int discount(StringGrade grade,int price){ int discountPercent=0; if(grade.equals(StringGrade.BASIC)) { discountPercent=10; }else if(grade.equals(StringGrade.GOLD)){ discountPercent=20; }else if(grade.equals(StringGrade.DIAMOND)){ discountPercent=30; }else{ System.out.println(grade+":할인 x"); } return price*discountPercent/100; } } discount 메서드에서 타입을 String 타입이 아닌 StringGrade타입으로 받으면 아래 예제가 다 에러 표시가 나면서 개발자들이 실수 하지않게 되는데? 왜 굳이 enum을 쓰나여? StringGrade타입으로 하면되자나여 package enumeration.ex1; import enumeration.ex1.DiscountService; public class StringGradeEx1_2 { public static void main(String[] args) { int price=100000; DiscountService discountService=new DiscountService(); //존재하지 않는 등급 int VIP =discountService.discount("VIP",price); System.out.println("VIP = " + VIP); //오타 int diamoddd= discountService.discount("diamoddd",price); System.out.println("diamoddd = " + diamoddd); //소문자 입력 int gold= discountService.discount("gold",price); System.out.println("gold = " + gold); } }
안녕하세요 크롤링이 뭔지 아예 모르다가 이게 조금씩 눈을 뜨고 있는 뉴비입니다~! 네이버 쇼핑 홈페이지 변경 및 HTML 구조 변경으로 설명이 한번 더 되면 좋겠습니다 강의에 나온 것처럼 나무태그를 찾으려 해도 현재 기준 네이버 쇼핑 HTML 구조를 현재 강의 내용을 기반으로 따라 할 수가 없습니다ㅠㅠ(상위 클래스로 검색해도 안나오는..??) https://search.shopping.naver.com/ns/search?query=%EB%8B%AD%EA%B0%80%EC%8A%B4%EC%82%B4 기회가 된다면 업데이트를.. 안된다면 유투브로 보여주셔도 짤막하게라도 보여주시면 좋을거 같습니다!! 감사합니다~!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] public static void printV2(Shuttle<? extends BioUnit> shuttle) { shuttle.showInfo(); } 이 부분에 와일드카드가 BioUnit 을 extends 해야 한다고 명시적으로 작성해 주고 있는데 Shuttle 클래스에서 이미 <T extends BioUnit> 을 하고 있기 때문에 와일드카드는 단순하게 ? 만 사용해도 괜찮은 걸까요? 다른 개발자가 사용할 경우에 좀 더 명시적으로 확인시켜주기 위해 적은거라고 이해해도 되는 건지 궁금합니다. public static void printV2(Shuttle<?> shuttle) { shuttle.showInfo(); } 이렇게 코드를 작성한 이후에 여러 테스트를 해봤는데 Shuttle 클래스를 만들때 <T extends BioUnit> 에 걸려서 Integer나 Object 등 다른 타입은 사용할 수 없더라구요.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요. 강의 너무 잘 듣고 있습니다! 현재까지 진행해온 프로젝트의 OrderController에도 Spring Rest Docs를 적용해보는 와중에 몇가지 질문이 생겼습니다! public class OrderControllerDocsTest extends RestDocsSupport { private final OrderService orderService = mock(OrderService.class); private static List<ProductResponse> productResponses; @Override protected Object initController() { return new OrderController(orderService); } @BeforeEach void init() throws Exception { ProductResponse productResponse1 = ProductResponse.builder() .id(1L) .price(1000) .sellingStatus(SELLING) .productNumber("001") .type(HANDMADE) .name("상품명1") .build(); ProductResponse productResponse2 = ProductResponse.builder() .id(2L) .price(3000) .sellingStatus(SELLING) .productNumber("002") .type(HANDMADE) .name("상품명2") .build(); productResponses = List.of(productResponse1, productResponse2); } @DisplayName("새로운 주문을 생성한다.") @Test void createOrder() throws Exception { //given LocalDateTime now = LocalDateTime.of(2025, 1, 28, 0, 50); List<String> productNumbers = List.of("001", "002"); OrderCreateRequest request = OrderCreateRequest.builder() .productNumbers(productNumbers) .build(); int totalPrice = productResponses.stream().mapToInt(ProductResponse::getPrice).sum(); OrderResponse orderResponse = OrderResponse.builder() .id(1L) .registeredDateTime(now) .products(productResponses) .totalPrice(totalPrice) .build(); given(orderService.createOrder(any(OrderCreateServiceRequest.class), any(LocalDateTime.class))) .willReturn(orderResponse); //when mockMvc.perform(post("/api/v1/orders/new") .content(mapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andDo(document("order-create", preprocessRequest(prettyPrint()), // adoc에서 json 형태를 보기 좋게 만들어줌 preprocessResponse(prettyPrint()), requestFields( fieldWithPath("productNumbers").type(JsonFieldType.ARRAY) .description("상품 리스트") ), responseFields( fieldWithPath("code").type(JsonFieldType.NUMBER) .description("코드"), fieldWithPath("status").type(JsonFieldType.STRING) .description("상태"), fieldWithPath("message").type(JsonFieldType.STRING) .description("메시지"), fieldWithPath("data").type(JsonFieldType.OBJECT) .description("응답 데이터"), fieldWithPath("data.id").type(JsonFieldType.NUMBER) .description("주문 ID"), fieldWithPath("data.totalPrice").type(JsonFieldType.NUMBER) .description("총 주문 가격"), fieldWithPath("data.registeredDateTime").type(JsonFieldType.ARRAY) // 반환타입 ARRAY ? .description("주문 시간"), fieldWithPath("data.products").type(JsonFieldType.ARRAY) .description("주문 상품 리스트"), fieldWithPath("data.products[].id").type(JsonFieldType.NUMBER) .description("주문 상품 ID"), fieldWithPath("data.products[].productNumber").type(JsonFieldType.STRING) .description("주문 상품 번호"), fieldWithPath("data.products[].type").type(JsonFieldType.STRING) .description("주문 상품 타입"), fieldWithPath("data.products[].sellingStatus").type(JsonFieldType.STRING) .description("주문 상품 상태"), fieldWithPath("data.products[].name").type(JsonFieldType.STRING) .description("주문 상품명"), fieldWithPath("data.products[].price").type(JsonFieldType.NUMBER) .description("주문 상품 가격") )) ); } } OrderService.createOrder() 메서드 반환 값 OrderResponse를 생성하기 위해선 ProductResponse 객체가 필요합니다. 이러한 경우가 강사님이 말씀하신 @BeforeEach의 적용시점인가? 라는 생각이 들어 위와 같이 작성해봤습니다. 제가 이해한 바가 맞을까요?? requestFields( fieldWithPath("productNumbers").type(JsonFieldType.ARRAY) .description("상품 리스트") ), 위 코드에서 productNumbers에 있는 각 원소의 타입이 String 인것을 API 문서에 나타내고 싶어 fieldWithPath("productNumbers[]").type(JsonFieldType.STRING 과 같이 작성해봤지만 타입 미스매칭 오류가 발생했습니다. responseFields에는 동일한 방법으로 List 순회에 성공했지만 requestFields 순회 문제는 해결하지 못했습니다. 혹시 방법이 있다면 알려주시면 감사하겠습니다!
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] build.gradle에 Hibernate5JakartaModule을 잘 등록하여 라이브러리 목록도 확인했습니다. 그런데 이렇게 오류가 뜹니다ㅠㅠ 빨간 줄에는 "Cannot return a value from a method with void result type" 라고 뜨는데 이유가 뭘까요..ㅠㅠ
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. 연관관계 양방향에 값을 입력해주는 부분에 대해서 이해한 것 같습니다. 아직 1차 캐시에만 존재하고 영속성 엔티티에 반영이 되지 않았기 때문에 객체로는 조회가 되지 않는 것으로 이해했습니다. 다만 궁금한 점이 기본키 전략을 auto_increment 같은 방식으로 한 경우에는 미리 한번 쿼리가 나간다고 이전 강의에서 배운 것이 생각났습니다. 강의에서도 기본키 전략은 동일한 것 같습니다. 기본키 전략 때문에 나간 쿼리가 반영이 안되는 이유가 따로 있을가요?
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 물리 트랜잭션과 논리 트랜잭션 중 물리 트랜잭션 만이 데이터베이스에 직접 커밋과 롤백 같은 영향력을 행사할 수 있음을 이해했습니다. 그렇다면 만약 아래와 같은 코드가 존재할 때, 트랜잭션 동작 방식에 대해서 제가 이해한 것이 맞는 지 질문 드리고 싶습니다. // AuthPacade 클래스의 메서드 public void withdraw(final long userId, final String code) { User user = userFinder.getUser(userId); externalService.revoke(user.getPlatform(), code, user.getSerialId()); authService.deleteUser(user); } 위의 코드는 userFinder.getUser() 메서드에서 @Transactional 이 걸려있고 authService.deleteUser() 메서드에서 @Transactional 이 걸려있는 상태입니다. 두 함수 모두 외부 호출이며 externalService.revoke 역시 외부 호출이지만 @Transactional이 적용되지 않는 상태입니다. 그렇다면 이 경우에는 userFinder.getUser() 을 실행할 때, 하나의 물리 트랜잭션이 실행되어 종료(커밋)된 후 revoke() 를 수행한 후에 다시 authService.deleteUser() 를 실행하면서 또 다른 물리 트랜잭션이 실행되는 것으로 저는 이해했습니다. 즉, externalService.revoke() 메서드를 호출할 때는 트랜잭션이 적용되지 않고 그 외의 다른 2개의 메서드에는 서로 다른 물리 트랜잭션이 적용되는게 맞는지 궁금합니다!! 공부를 해보니 외부 네트워크와 통신하는 것은 트랜잭션 범위에서 제거하는 것이 좋다는 것을 깨달아서 배운 바를 토대로 개인 프로젝트에 적용해보는 중인데, 맞는 지 궁금합니다.. 특히, 실무에서는 어떤 방식으로 처리하는 지도 함께 궁금합니다! 감사합니다:)
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
강의따라서 H2접속하면 자동으로 BOOK, FRUIT, PERSON, USER, USER_LOAN_HISTORY 테이블이 있는데 어떻게 자동으로 만들어져 있는 건가요.?? mysql에서 테이블 만들었는데 h2는 mysql과 다른거 아닌가요..? 기존의 자바 entity 코드를 다 읽어서 얘네가 알고있는건가요??? ps. 강의 너무 잘듣고 있습니다! 이때까지 완강해본 강의가 손에꼽는데 완강을 앞두고 있어서 너무 설레는 맘입니다..! 좋은 강의 만들어주셔서 감사합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오)네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)아니오 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)네 [질문 내용] 여기에 질문 내용을 남겨주세요. spring.datasource.username=sa를 추가하였고, javax를 jakarta로 변경하였는데도 오류가 납니다. external libraries에 hibernate를 검색해도 나오지 않습니다. 틀린부분 알려주시면 감사하겠습니다.
게시글 CRUD API 구현 테스트 하는 부분에서 13:34쯤에 작성하고 테스트 실행하는 부분에서 아래 오류가 발생하는데 원인이 도대체 뭐일까여..ㅠㅠ 포트 9000에 서버 시작도 해놨었습니다 500 Internal Server Error: "{"timestamp":"2025-01-27T06:39:44.186+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles"}" org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "{"timestamp":"2025-01-27T06:39:44.186+00:00","status":500,"error":"Internal Server Error","path":"/v1/articles"}" at org.springframework.web.client.HttpServerErrorException.create(HttpServerErrorException.java:102)
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 대상 강의록: 4. 컬렉션 프레임워크 - LinkedList.pdf 의 p.12 대상 소스 파일: NodeMain3 add(Node node, String param) 메서드 건의 내용: 해당 부분은 아직 LinkedList 에 대한 제네릭 도입 전이므로 Node 클래스에서도 item 의 타입을 Object 로 사용하고 있습니다. public class Node { Object item; Node next; public Node(Object item) { this.item = item; } ... } 따라서 add 메서드 또한 추가할 데이터인 param을 String이 아닌, Object 타입으로 설정해야 수강생들의 이해가 쉬울 것이라고 생각합니다. // 기존 강의록 코드 private static void add(Node node, String param) { Node lastNode = getLastNode(node); lastNode.next = new Node(param); } // 수정 제안 코드 <<수정부분: String -> Object>> private static void add(Node node, Object param) { Node lastNode = getLastNode(node); lastNode.next = new Node(param); }