안녕하세요. 데이터 수정은 변경 감지로 처리하는게 적절한걸로 강의를 통해 이해했습니다. 강의를 학습 후, 상품 정보를 수정하는 API를 개발하고 있습니다. 상품 정보 업데이트를 진행할 때 옵션 목록과 같은 하위 데이터에 대해 추가, 삭제는 어떤식으로 로직을 처리해야 하는게 적절한지 판단이 안되어 질문 드립니다. 클라이언트에서 상품 정보 수정 API를 호출할 때, 생각한 프로세스는 아래와 같습니다. - 수정하는 옵션의 경우 ID와 변경되는 데이터를 필드에 담아서 보내줍니다. - 신규 옵션을 추가하는 경우에는 ID를 제외한 추가될 데이터를 필드에 담아서 보내줍니다. - 삭제하는 옵션은 필드에 담지않고, 수정/신규 옵션만 필드에 담아서 보내줍니다. 수정 API 개발할 때, 어떤식으로 처리하는게 좋은 방법인지 궁금하여 질문 드립니다. (수정 옵션) 상품 정보 업데이트 시 기존 옵션 데이터의 경우에는 ID로 데이터를 조회 후 변경 감지로 필요한 데이터만 수정하도록 했습니다. (추가 옵션) 신규 옵션 데이터는 ID 값이 없는걸 식별해서 추가하도록 로직을 짜는게 적절 할까요? (삭제 옵션) 기존 옵션 데이터를 삭제하고 싶습니다. 클라이언트에서 API로 옵션 정보를 넘겨주는데, 삭제되는 옵션은 넘어오지 않습니다. 이런 경우에는 ID가 식별되지 않아 변경 감지로 삭제할 수가 없을거 같은데 어떻게 해야할까요? (삭제는 soft delete 방식으로 처리해야 합니다.) 삭제되는 ID 값을 deleteOptionIds 같은 필드로 따로 받아서 처리하는게 적절 할까요? 감사합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 테스트코드를 수행하였을때 Creating shared instance of singleton bean xxx 이런 메세지가 나오지 않습니다. 어떻게해야 이 메세지를 확인할 수 있는지 환경 설정과 같은 설정 내용을 안내해 주실 수 있을까요
[질문 내용] 아래와 같은 오류가 발생합니다. Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2024-12-26T08:17:35.759+09:00 ERROR 30104 --- [servlet] [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletComponentRegisteringPostProcessor': Instantiation of supplied bean failed at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1239) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:288) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.context.support .PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:202) ~[spring-context-6.2.0.jar:6.2.0] at org.springframework.context.support .AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.0.jar:6.2.0] at org.springframework.context.support .AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.0.jar:6.2.0] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.SpringApplication.run (SpringApplication.java:318) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.SpringApplication.run (SpringApplication.java:1361) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.SpringApplication.run (SpringApplication.java:1350) ~[spring-boot-3.4.0.jar:3.4.0] at hello.servlet.ServletApplication.main(ServletApplication.java:12) ~[classes/:na] Caused by: java.lang.NoClassDefFoundError: jakarta/servlet/annotation/WebServlet at org.springframework.boot.web.servlet.WebServletHandler.<init>(WebServletHandler.java:39) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.web.servlet.ServletComponentRegisteringPostProcessor.<clinit>(ServletComponentRegisteringPostProcessor.java:60) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.boot.web.servlet.ServletComponentScanRegistrar$ServletComponentRegisteringPostProcessorBeanDefinition.lambda$getInstanceSupplier$0(ServletComponentScanRegistrar.java:94) ~[spring-boot-3.4.0.jar:3.4.0] at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1273) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:981) ~[spring-beans-6.2.0.jar:6.2.0] at org.springframework.beans.factory.support .AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1233) ~[spring-beans-6.2.0.jar:6.2.0] ... 16 common frames omitted Caused by: java.lang.ClassNotFoundException: jakarta.servlet.annotation.WebServlet at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na] ... 22 common frames omitted Process finished with exit code 1
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 회원가입을 할 때 요청하는 정보를 @Valid를 사용해 검증 이후 @ExceptionHandler를 사용해서 원하는 오류의 형식을 응답하는 방식으로 코드를 짜보려고 합니다. @Valid로 발생하는 BindException 혹은 MethodArgumentNotValidException을 @ExceptionHandler로 잡아서 처리를 해야 하는 점은 이해했는데 의도적으로 예외를 발생시킨 뒤 postman을 통해 오류가 발생했는지 확인해보면 null값이 그대로 저장이 되어있습니다. 아직 예외를 처리하지 않았기 때문에 BindException 혹은 MethodArgumentNotValidException 예외가 발생해야하는 것 아닌가요? 어느 부분에서 문제가 있는지 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. @GetMapping("/members") public Page<?> list(@PageableDefault(size = 5, sort = "id", direction = Sort.Direction.DESC) Pageable pageable) { return repository.findAll(pageable).map(MemberResponse::new); } 해당 코드에서 API를 호출했는데 Serializing PageImpl instances as-is is not supported, meaning that there is no guarantee about the stability of the resulting JSON structure! For a stable JSON structure, please use Spring Data's PagedModel (globally via @EnableSpringDataWebSupport(pageSerializationMode = VIA_DTO)) or Spring HATEOAS and Spring Data's PagedResourcesAssembler as documented in https://docs.spring.io/spring-data/commons/reference/repositories/core-extensions.html#core. 이러한WARN 문구가 출력되었습니다. 이는 PageImpl의 객체가 그대로 JSON으로 직렬화되어 구조적인 문제가 발생할 수 있다는 경고 메세지 인데 이를 해결하기 위해서는 HATEOAS 의존성을 주입받아서 PagedModel을 반환하는 방법이 있고 spring.data .web.pageable.serialization-mode=via-dto 해당 코드를 yml 파일에 추가해서 글로벌 설정으로 가져가는 방법이 있고 @EnableSpringDataWebSupport(pageSerializationMode = VIA_DTO)) 방법이 있다고 합니다. 강사님 영상에는 해당WARN 문구가 보이지 않는데 그 이유는 버전의 문제때문에 강사님 영상에는 해당 WARN 문구가 보이지 않는게 싶습니다. 제가 가장 궁금한 것은 물론 프로젝트의 비즈니스에 따라 다르겠지만 위의 방법들중 어떤 방법이 가장 보편적으로 쓰이나 궁금합니다
[질문 내용] Book 외에 Album, Moive도 구현하려고 합니다. 예제의 itemList.html에는 추상 클래스 Item에 정의된 속성들만 표시되도록 되어있는데요. Item이 Book인 경우에는 author, isbn이 Album인 경우에는 artist, etc 등이 같이 표시되도록 하려면 어떻게 구현하는 것이 가장 좋은 방법일까요? 타임리프에서 Item의 클래스를 체크한 후(instance of 와 유사) 다운캐스팅해서 각각의 타입에만 해당하는 내용을 출력하는 방식으로 구현하고, href도 "items/{id}/edit"을 수정해서 "items/{id}/book-edit", "items/{id}/album-edit"과 같은 식으로 하는게 맞는 방법인가요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요. errors.properties에 궁금한 점이 있어 문의드립니다. 파라미터가 존재하는 메시지에 new Object[]{1000, 1000000}로 매개변수를 전달하였을 때, 자동으로 1,000 / 1,000,000와 같이 쉼표가 포함되는 숫자로 표시되는데 숫자인 경우엔 쉼표를 자동으로 넣어주는건가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요. 실무를 하는데 궁금한게 있어 질문 남깁니다. repository 인터페이스에 생성된 메소드를 실행하는데 string으로 파라미터 값을 보내주는 예제를 보여주셨는데, 혹시 vo를 바로 보내줄수도 있을까요? 가능하다면 어떤 형식으로 가능할지 궁금합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니요 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요, 스프링 입문 강의 수강 중 문의드리고 싶어 글을 남깁니다. 강사님 말씀대로 hellospringapplication을 실행하니 붉은 색 글씨로 아래 문구처럼 출력됩니다. Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build what is described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3 WARNING: A Java agent has been loaded dynamically (/Users/user/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.15.11/a38b16385e867f59a641330f0362ebe742788ed8/byte-buddy-agent-1.15.11.jar) WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information WARNING: Dynamic loading of agents will be disallowed by default in a future release OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 자바는 openjdk oracle 23.0.1을 사용 중이고, gradle jvm도 oracle openjdk 23 버전을 사용 중입니다. 제공해주신 다른 답변들을 확인하여 자바 버전을 17로 다운그레이드 하려 했는데 project structure에서 17 버전을 선택하니 amazon corretto가 선택되었습니다. 오라클 17 버전은 따로 뜨지가 않더라고요.. 오라클 버전 외 다른 17 버전을 선택하고 gradle jvm도 조정하면 해결될까요, 아니면 다른 방법이 있을까요 ? 양질의 컨텐츠 제공해주셔서 항상 감사드립니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 강의에서 나오는데로 orderCount를 11로 하면 need more stock jpabook.jpashop.exception.NotEnoughStockException: need more stock at jpabook.jpashop.domain.item.Item.removeStock(Item.java:43) at jpabook.jpashop.domain.OrderItem.createOrderItem(OrderItem.java:44) at jpabook.jpashop.service.OrderService.order(OrderService.java:38) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.springframework.aop.support .AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:727) at jpabook.jpashop.service.OrderService$$SpringCGLIB$$0.order(<generated>) at jpabook.jpashop.service.OrderServiceTest.상품주문_재고수량초과(OrderServiceTest.java:56) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:76) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 2024-12-22T17:33:07.127+09:00 INFO 5250 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2024-12-22T17:33:07.128+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists category cascade 2024-12-22T17:33:07.129+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387129 | took 1ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists category cascade drop table if exists category cascade ; 2024-12-22T17:33:07.129+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists category_item cascade 2024-12-22T17:33:07.130+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387130 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists category_item cascade drop table if exists category_item cascade ; 2024-12-22T17:33:07.130+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists delivery cascade 2024-12-22T17:33:07.130+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387130 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists delivery cascade drop table if exists delivery cascade ; 2024-12-22T17:33:07.130+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists item cascade 2024-12-22T17:33:07.131+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387131 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists item cascade drop table if exists item cascade ; 2024-12-22T17:33:07.131+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists member cascade 2024-12-22T17:33:07.131+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387131 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists member cascade drop table if exists member cascade ; 2024-12-22T17:33:07.131+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists order_item cascade 2024-12-22T17:33:07.131+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387131 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists order_item cascade drop table if exists order_item cascade ; 2024-12-22T17:33:07.131+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop table if exists orders cascade 2024-12-22T17:33:07.132+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387132 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop table if exists orders cascade drop table if exists orders cascade ; 2024-12-22T17:33:07.132+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists category_seq 2024-12-22T17:33:07.132+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387132 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists category_seq drop sequence if exists category_seq; 2024-12-22T17:33:07.132+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists delivery_seq 2024-12-22T17:33:07.132+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387132 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists delivery_seq drop sequence if exists delivery_seq; 2024-12-22T17:33:07.132+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists item_seq 2024-12-22T17:33:07.133+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387133 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists item_seq drop sequence if exists item_seq; 2024-12-22T17:33:07.133+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists member_seq 2024-12-22T17:33:07.133+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387133 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists member_seq drop sequence if exists member_seq; 2024-12-22T17:33:07.133+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists order_item_seq 2024-12-22T17:33:07.133+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387133 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists order_item_seq drop sequence if exists order_item_seq; 2024-12-22T17:33:07.133+09:00 DEBUG 5250 --- [ionShutdownHook] org.hibernate.SQL : drop sequence if exists orders_seq 2024-12-22T17:33:07.133+09:00 INFO 5250 --- [ionShutdownHook] p6spy : #1734856387133 | took 0ms | statement | connection 14| url jdbc:h2:mem:3e9d99ac-3e6a-493e-ba08-cc03d272eaed drop sequence if exists orders_seq drop sequence if exists orders_seq; 2024-12-22T17:33:07.135+09:00 INFO 5250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2024-12-22T17:33:07.137+09:00 INFO 5250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. > Task :test FAILED OrderServiceTest > 상품주문_재고수량초과 FAILED jpabook.jpashop.exception.NotEnoughStockException at OrderServiceTest.java:56 1 test completed, 1 failed FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > There were failing tests. See the report at: file:///Users/iyeonseo/Downloads/jpashop/build/reports/tests/test/index.html * Try: > Run with --scan to get full insights. BUILD FAILED in 4s 5 actionable tasks: 2 executed, 3 up-to-date 이런 에러가 뜹니다. 강의에서는 성공이 뜨는데 왜 이렇게 뜨는건가요
package hallo.core; import hallo.core.discount.FixDiscountPolicy; import hallo.core.member.MemberRepository; import hallo.core.member.MemberService; import hallo.core.member.MemberServiceImpl; import hallo.core.member.MemoryMemberRepository; import hallo.core.order.OrderService; import hallo.core.order.OrderServiceImpl; public class AppConfig { //생성자 주입 // -> MemberServiceImpl 은 추상에만 신경쓴다. 따라서 // new MemoryMemberRepository() 객체가 AppConfig 외부에서 생성되어 들어간다 //MemberServiceImpl 를 생성하면서 MemoryMemberRepository 를 쓸거야! //AppConfig는 생성자 객체인스턴의 참조(레퍼런스)를 생성자를 통해서 주입(연결 한다) public MemberService memberService() { return new MemberServiceImpl(new MemoryMemberRepository()); } //------생성자를 통한 참조 주입(1) ---------------------------------------- // MemberService() 메서드가 호출되면 new MemoryMemberRepository()가 실행되어 //MemoryMemberRepository() 객체가 생성 된다. 이 객체의 참조값(메모리 주소)이 //MemberServiceImpl의 생성자 매개변수로 전달된다 public OrderService orderService() { return new OrderServiceImpl( new MemoryMemberRepository(), new FixDiscountPolicy()); } } public class MemberServiceImpl implements MemberService { private MemberRepository memberRepository; // AppConfig 에서 관리 //AppConfig 는 생성자 객체인스턴의 참조(레퍼런스)를 생성자를 통해서 주입(연결 한다) public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; } //------생성자를 통한 참조 주입(2) ---------------------------------------- //전달받은 참조값을 MemberServiceImpl 클래스의 필드인 memberRepository에 할당. //MemberServiceImpl 인스턴스의 memberRepository 필드는 AppConfig에서 생성된 MemoryMem berRepository //객체의 참조값을 가지게 된다. //AppConfig에서 생성된 MemoryMemberRepository 객체의 참조값은 매개변수 memberRepository -> 필드 memberRepository 순서로 //전달되어 최종적으로 클래스 필드에 저장된다. } 생성자를 통한 참조 주입을 제가 정리해 보았습니다. 실제로 메모리에 할당 될 때 [AppConfig] new MemoryMemberRepository() -----> 메모리 주소(예: x001) ↑ [MemberServiceImpl] | memberRepository -------------------| 이렇게 할당이 될 것이라고 생각하는데 제가 정리한 것과 흐름이 맞는지 궁금합니다. 그리고 MemoryMemberRepository()); 이 부분은 객체생성을 하면서 참조값을 만들지만 참조값을 받는 변수가 없는데 어떻게 참조값을 인식하는지 궁금합니다. 답변 주시면 감사하겠습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.
요청 기반 권한 부여 - HttpSecurity.securityMatch 강의 (14분 25초) 를 듣고 코드를 똑같이 따라 치고 실행해보니 에러가 뜨면서 동작을 안 하더군요. spring boot 버전은 3.4.1 + spring security 6.4.2 로 테스트를 해봤습니다. 조사를 해보니 에러를 뱉는 건 스프링 시큐리티의 WebSecurity 클래스였고, 아래 빨간 박스 친 부분에서 에러를 뱉습니다. 이 코드는 securityMatcher 를 설정 안 한 SecurityFilterChain, 즉 anyRequestFilterChain 이 모든 FilterChain 들 보다 항상 뒤편에 있어야 되는 것을 보장하기 위한 유효성 검사를 위한 것입니다. 선생님이 강의를 찍던 당시와 달라진 내용이 아닐까 싶습니다. 아무튼 이를 우회해서 테스트를 할 수 있는데, 선생님이 작성하신 코드에서 딱 한줄만 추가해주면 됩니다. @Bean @Order(1) public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // !!!!!!!!!!!!!!! 아래 한 줄 추가 !!!!!!!!!!!!!!! http.securityMatchers(matcher -> matcher.requestMatchers("/**")); http.authorizeHttpRequests(auth -> { auth.anyRequest().authenticated(); }) .formLogin(Customizer.withDefaults()); return http.build(); } @Bean public SecurityFilterChain securityFilterChain2(HttpSecurity http) throws Exception { http.securityMatchers(matchers -> matchers.requestMatchers("/api/**", "/oauth/**")); http.authorizeHttpRequests(auth -> { auth.anyRequest().permitAll(); }); return http.build(); } 이상으로 내용 공유를 마칩니다.
OneToMany 관계에서 페치조인을 하게되면 페이징이 불가하다고 하셨는데 OneToMany는 batchSize를 조절하여 해결한뒤 OneToMany안의 ManyToOne 관계는 어떻게 페치조인 할수있을까요? 예를 들어서 테이블 A, B, C가 있을경우 A와 B는 OneToMany관계 B와 C는 ManyToOne관계 class A { @OneToMany private List<B> b = new ArrayList<>(); } class B { @ManyToOne // Lazy private A a; @ManyToOne // Lazy private C c; } class C { } A를 조회하고 C까지 끌고와야하는경우 A와 B는 OneToMany 관계이기 때문에 페치조인이 불가능하지만 B와 C는 페치조인이 가능하다고 이해하였습니다 BatchSize를 설정하여 A에서 B를 가져올시 IN 쿼리로 가져온뒤 B에서 C를 페치 조인하는 방법은 없나요? 아니면 이런경우 특수하게 B에서 C를 Eager로 설정 해야할까요 애초에 B를 통해서 A와 C를 가져와야할까요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. could not prepare statement [Sequence "MEMBER_SEQ" not found; SQL statement: select next value for member_seq [90036-232]] [select next value for member_seq]; SQL [select next value for member_seq] org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement [Sequence "MEMBER_SEQ" not found; SQL statement: select next value for member_seq [90036-232]] [select next value for member_seq]; SQL [select next value for member_seq] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:277) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) at org.springframework.dao.support .ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) at org.springframework.dao.support .DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343 ) 이런 에러가 납니다ㅠㅠ