묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 데이터 JPA
Slice 방식에서의 엔티티를 DTO 로 변환
Page 방식에서 api response 를 줄 때 엔티티-> DTO 변환은 Page 인터페이스에서 지원하는 map 을 이용하는 것이라고 이해했습니다.Slice 인터페이스의 스펙에는 map 함수가 없던데 Slice 를 사용할 때 엔티티-> DTO 변환은 어떻게 해야 하나요?
-
미해결스프링부트 개념정리(이론)
JPA가 저장되는 위치는 어디인가요?
JPA가 저장되는 위치는 어디인가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
H2 설치 후 실행관련 (윈도우 환경)
설치 후 실행하면 이렇게 되는데, 뭐로 실행해야 하나요?강의내용 보니 브라우저 환경에서 콘솔이 실행된 것 같은데 막상 해당 파일은 크롬에서 실행하는것도 아닌듯 한데요..
-
미해결스프링 시큐리티 OAuth2
HttpServletRequest.getHader("Authorization") 값 null
안녕하세요 강사님, 외람되지만 강의부분 살짝 외 부분을 질문 드립니다.(계속 인터넷 서칭을 하면서 고쳐도 해결되지 않아 죄송함을 무릅쓰고 질문 드립니다.)OAuth2.0 + JWT를 합쳐서 구현했습니다.JwtAuthenticationFilter를 구현하고 클라이언트로부터 받은 request의 Header의 Authorizaiton을 가져오는 로직에서 계속 null로 들어오는데 혹시 어떤 문제가 있는지 알 수 있을까요?public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider jwtTokenProvider; private final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationFilter.class); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = parseBearerToken(request); // Validation Access Token if (StringUtils.hasText(token) && jwtTokenProvider.validateToken(token)) { Authentication authentication = jwtTokenProvider.getAuthentication(token); SecurityContextHolder.getContext().setAuthentication(authentication); LOGGER.info(authentication.getName() + "의 인증정보 저장"); } else { LOGGER.info("유효한 JWT 토큰이 없습니다."); } filterChain.doFilter(request, response); } private String parseBearerToken(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); System.out.println(request.getHeader("Authorization")); if (bearerToken != null && bearerToken.startsWith("Bearer")) { return bearerToken.substring(7); } return null; }
-
미해결스프링 부트 - 핵심 원리와 활용
서버 증설 기준이 되는 CPU, 메모리 사용량
서버 증설 기준이 되는 CPU, 메모리 사용량 등은 서버마다 회사마다 팀마다 정하기 나름인가요? 아니면 통용되는 %가 있나요?
-
미해결스프링 부트 - 핵심 원리와 활용
private 함수 흐름 모니터링
추천해주신 핀포인트로 어떤 함수가 호출되었는지 파악하던 중 private 함수 호출 흐름은 핀포인트에서 알기 어렵더라구요. 혹시, private 함수 호출 흐름을 파악하실 때, 어떤 방법을 사용하시나요? private 함수 내의 로그를 하나하나 작성해주시나요?
-
미해결토비의 스프링 부트 - 이해와 원리
PropertySourcesPlaceholderConfigure에 대해 질문있습니다.
먼저 양질의 강의를 제공해주신 점에서 매우 감사하다는 말씀을 드리고 있습니다. 강의에서 /app란 값을 @Value로 주입을 해줬을때 ${contextPath}만 출력이 되는 부분에 질문이 있습니다. 제가 이해하기로는 커스텀 빈들이 먼저 주입이 되기 때문에 실제로 스프링부트의 인프라스트럭처 빈인 PropertySourcesPlaceholderConfigurer가 주입이 되지 않아 ${contextPath}가 나온다고 이해를 했습니다.제가 이해한게 맞다면 빈의 주입 순서에 따라 @Value의 값이 달라진다는 것인데, 만약 tobyspring.config.autoconfig.PropertyPlaceholderConfig 이 클래스가 tobyspring.config.autoconfig.TomcatWebServerConfig 이 클래스보다 더 늦게 주입이 된다면 여전히 ${contextPath}가 나오게 되는지 궁금합니다!또한 테스트를 한 번 해보고싶어서 계속해서 시도해봤지만 테스트 방법이 도저히 감이 오질않는데, 이럴 때는 어떻게 테스트를 하면 되는지 알 수 있을까요?
-
해결됨스프링 시큐리티 OAuth2
디폴트 로그인페이지인 /login 페이지에 대해 질문있습니다.
안녕하세요 강사님. 13분 20 초쯤 보시면 디폴트 로그인 페이지에서 href 걸려있는 oauth2-client-app이라는 링크를 누르게 되면 인가서버의 로그인페이지로 이동하는 것을 보실 수 있습니다. 여기서 제가 궁금한 것은 oauth2-client-app 이라는 링크를 누르는 순간 /oauth2/authorization/keycloak 경로의 요청이 Client 로 보내지게 되고, Client 에서 해당 경로로 요청이 들어오길 기다리고있던OAuth2AuthorizationRequestRedirectFilter 가 내부적으로 권한부여 요청을 보낼 수 있는 uri 인 authorization-uri 로 Redirection 시키게되어 현재 로그인페이지로 이동한것인가요? 보다 정확하게 알고싶어 이렇게 질문드립니다!! 아 그리고 강의 너무나도 잘듣고있습니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
java.lang.IllegalStateException: Failed to load ApplicationContext 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.[질문 내용]MemberRepositoryTest에서 계속 오류가 발생합니다.강사님이 진행 하시는 대로 똑같이 쳤고 강의 자료에서 하라는 것 까지 다 해보고 이것저것 몇시간을 해봤는데 계속 오류가 나요...근데 특이한 점은 다른 분들은 처음부터 안된다고 하시는데 저는 처음에 h2 DB파일 생성한 다음 localhost모드로 바꿔서 들어가고 나서 Test를 돌리면 성공을 합니다.실제로 테이블도 생성되구요.근데 그 다음부터 두번째 부터는 계속 Failed to load ApplicationContext 오류가 발생합니다...membermemberRepositorymemberRepositoryTestdb 첫 생성시에는 성공 이후로 계속 오류build.gradle파일...부트버전은 3.1.2구요 그래서 junit5를 사용했습니다.application.yml파일 java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@1573e8a5 testClass = jpabook.jpashop.MemberRepositoryTest, locations = [], classes = [jpabook.jpashop.JpashopApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@1b2abca6, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@342c38f8, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@54bff557, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@4dbb42b7, org.springframework.boot.test.context.SpringBootTestAnnotation@4ec067d1], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:143) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278) at java.base/java.util.Optional.orElseGet(Optional.java:364) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277) at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1155) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1406) at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:545) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:187) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:119) ... 72 moreCaused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1817) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ... 93 moreCaused by: org.hibernate.MappingException: Could not instantiate id generator [entity-name=jpabook.jpashop.Member] at org.hibernate.id.factory.internal.StandardIdentifierGeneratorFactory.createIdentifierGenerator(StandardIdentifierGeneratorFactory.java:230) at org.hibernate.id.factory.internal.IdentifierGeneratorUtil.createLegacyIdentifierGenerator(IdentifierGeneratorUtil.java:126) at org.hibernate.mapping.SimpleValue.createGenerator(SimpleValue.java:414) at org.hibernate.internal.SessionFactoryImpl.lambda$createGenerators$1(SessionFactoryImpl.java:413) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1779) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) at org.hibernate.internal.SessionFactoryImpl.createGenerators(SessionFactoryImpl.java:412) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:249) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:431) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1455) at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ... 97 moreCaused by: org.hibernate.HibernateException: Could not fetch the SequenceInformation from the database at org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.sequenceInformationList(ExtractedDatabaseMetaDataImpl.java:307) at org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.getSequenceInformationList(ExtractedDatabaseMetaDataImpl.java:151) at org.hibernate.id.enhanced.SequenceStyleGenerator.getSequenceIncrementValue(SequenceStyleGenerator.java:568) at org.hibernate.id.enhanced.SequenceStyleGenerator.configure(SequenceStyleGenerator.java:216) at org.hibernate.id.factory.internal.StandardIdentifierGeneratorFactory.createIdentifierGenerator(StandardIdentifierGeneratorFactory.java:224) ... 116 moreCaused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "start_value" not found [42122-214] at org.h2.message.DbException.getJdbcSQLException(DbException.java:502) at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) at org.h2.message.DbException.get(DbException.java:223) at org.h2.message.DbException.get(DbException.java:199) at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3492) at org.h2.jdbc.JdbcResultSet.getLong(JdbcResultSet.java:745) at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.resultSetStartValueSize(SequenceInformationExtractorLegacyImpl.java:110) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.lambda$extractMetadata$0(SequenceInformationExtractorLegacyImpl.java:54) at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:50) at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:39) at org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl.sequenceInformationList(ExtractedDatabaseMetaDataImpl.java:291) ... 120 moreㅜㅜ 진짜 3시간째 이거 잡고있는데 이유를 모르겠어요
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
모든 섹션 강의자료
안녕하세요. 이번에 새로 수강할려고 하는데 혹시 모든 섹션 강의자료는 어디서 다운받을 수 있을까요?
-
미해결스프링 시큐리티 OAuth2
소셜 로그인 관련 질문드립니다!!
안녕하세요 강사님, 강의 정말 잘 듣고 혼자 힘으로 최대한 자료 안보면서 머리 싸매면서 구현해보고 있습니다. 강의 후반부 까지 듣다가 잠시 중단하고 긴가민가 한 부분만 찾아서 다시 듣고 있는 상황입니다. 사진은 ChatGPT 로그인 화면이고 구현하고자 하는 목표입니다.다만, Session 을 사용하지 않으려고 합니다. 거기에 많은 분들이 질문하신 소셜 로그인 이후에 토큰을 가지고 서버에 인가를 요청하는 과정을 구현하고자 합니다.그리고 아래는 제가 이렇게 구현하면 되지 않을까? 생각한 내용이고, 한번 시간내서 봐주시면 정말 감사하겠습니다. (질문시작)AuthorizationRequestRepository<OAuth2AuthorizationRequest>강의에서도 나오지만 OAuth 2.0 가 default 로 Authorization Request 를 Session 에 저장합니다. 이를 그대로 사용하지 않고 Cookie 에 저장하기 위해서 다른 블로그를 참고했습니다.@Override public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { return CookieUtil.getCookie(request, OAUTH2_AUTHORIZATION_COOKIE_NAME) .map(cookie -> CookieUtil.deserialize(cookie, OAuth2AuthorizationRequest.class)) .orElse(null); } @Override public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, HttpServletResponse response) { if(authorizationRequest == null) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); return; } CookieUtil.addCookie(response, OAUTH2_AUTHORIZATION_COOKIE_NAME, CookieUtil.serialize(authorizationRequest), cookieExpireSeconds); String redirectUrlAfterLogin = request.getParameter(REDIRECT_URI_PARAM_COOKIE_NAME); if (StringUtils.isNotBlank(redirectUrlAfterLogin)) { CookieUtil.addCookie(response, REDIRECT_URI_PARAM_COOKIE_NAME, redirectUrlAfterLogin, cookieExpireSeconds); } } @Override public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { return this.loadAuthorizationRequest(request); } public void removeAuthorizationRequestCookies(HttpServletRequest request, HttpServletResponse response) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); } 이후 OAuth 2.0 로그인에 성공 이벤트를 처리할 successfulHandler 를 생성합니다.@Component public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { // Token 유효성 검사 // Token 생성 // redirect_uri 로 사용자 redirect }여기까지 과정을 간단요약해 보겠습니다.유저가 소셜 로그인 버튼(google, github, kakao) 을 누른다.스프링부트 서버에서 /oauth2/authorization/${provider}?redirect_uri=http://localhost:3000/oauth/redirect 로 인가서버에게 요쳥을 보낸다.인가서버마다 설정된 authorization_code 의 엔드포인트로 redirect 된다.획득한 authorization_code 를 인가서버가 다시 스프링부트 서버로 전송한다.스프링부트 서버에서 다시 authorization_code 를 사용해서 access_token 을 요청한다. 인가서버는 access_token 을 스프링부트 서버로 전송한다. 스프링부트 서버는 access_token 을 이용해서 리소스 서버에 user_info 를 요청한다. 소셜 로그인인 경우, 인가서버와 리소스 서버가 동일하다.스프링부트 서버는 user_info 를 획득한다. 해당 정보를 DB 에 저장한다.그리고 스프링부트 서버에서 access_token 과 refresh_token 을 생성한다.refresh_token 은 수정이 불가능한 cookie 에 저장하고, access_token 은 프론트엔드로 redirect_uri 의 query-string 에 담아서 보낸다. 해당 access_token 은 localStorage 에 저장한다.혹은 refresh_token 은 스프링부트 서버가 가지고 있으며 DB 에 저장하고, access_token 만 cookie 에 담아서 프론트엔드에 보낸다.프론트엔드 서버에서 스프링부트 서버에서 전달받은 토큰을 localStorage 에 저장하고, 다시 스프링부트 서버로 요청을 보낼시 Authorization: Bearer ${access_token} 을 HTTP 헤더에 담아서 보낸다.스프링부트 서버에서 JwtDecoder 를 이용해서 access_token 을 검증한다. 만약 expiration date 가 지났다면 access_token 과 refresh_token 을 모두 재발급한다. (혹은 access_token 만 재발급한다) 출처는 이곳 입니다. (질문1)위의 순서가 합당하다면 강의 내용을 바탕으로 제가 추가적으로 구현할 부분은 스프링부트 서버에서 access_token, refresh_token 을 생성하는 로직(세션을 비활성화하고) 토큰을 cookie 에 담아서 보내는 로직스프링부트 서버에서 access_token 을 검증하고 재발급하는 로직인게 맞는건지 궁금합니다. (질문2)외부 인가서버를 사용하지 않고 OAuth 2.0 Resource Server, Client, Authorization Server 를 사용해서 스프링부트 서버가 모든 인증 & 인가의 책임을 가지게 된다면, 결국 google, github, naver 등의 외부 인가서버를 이용하는 것과 크게 차이가 나지 않는건가요? 어짜피 많은 부분을 OAuth 2.0 라이브러리가 지원해준다면, 외부 인가서버를 도입해서 커플링 시키느니 공공기관 납품하는 경우에는 직접 인가서버, 리소스서버를 구현하는 것이 더 실무에서 자주 일어나는 일인지 궁금합니다.(* 제가 일하던 작은 si 회사에서는 참여했던 프로젝트가 공공기관 프로젝트가 폐쇄망에서만 실행되는 내부 관리자 용이여서 보안 관련된 아주 간단한 설정만을 접해봤습니다.)(그리고 아직 강의 후반부 통합 연동부분을 다 듣지 못했습니다 ㅜ.ㅜ) (질문3)Keycloak, Okta 같은 오픈소스 인가서버를 사용하는 경우 토큰 관리, 세션 관리, 유저 관리 등이 개발자가 뭘 해줄것도 없이 인가서버에서 관리를 해줘서 굉장히 편하다는 것을 이해했습니다. 하지만 검색을 좀 해봐도 관리자가 한땀한땀 인가서버에 등록해주는 것이 아니라 일반적인 사이트에서 처럼 form 요청으로 키클록 서버에 자동으로 User 정보가 등록되는 것이 가능한지 모르겠습니다.보안이 중요한 기관에서 로그인 요청을 보내고, 며칠뒤에 계정이 만들어지는 것이 이런 프로그램을 이용해서인가.. 싶기도 하고 궁금하네요.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
hello.html 404 에러가 나옵니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]개인적인 사정으로 인해 인텔리제이가 아닌 codespace ide를 사용해서 수강중입니다.controller 파일과 hello.html 파일 둘 다 pdf 에서 그대로 복사하여 실행했는데 404에러가 나옵니다.문제가 무엇일까요
-
미해결스프링 시큐리티
예외처리 동작과정
안녕하세요 강의 디버깅중에저희가 본 내용은 여기입니다. 그런데 위에 보시면 169라인 exception instanceof AuthenticationException 인증예외도 잡더라구요. 그런데 저부분은 현재 강의에선 이용하지않고 지금 강의는 AuthenticationFailureHandler 를 별도로 상속받아 클래스를 만들어 처리하고 있다고 생각하면 될까요 ?
-
미해결스프링 시큐리티
강의 내용 질문
안녕하세요 강의 너무 최고입니다.질문이 있습니다. !! 첫번째 질문은http.exceptionHandling().authenticationEntryPoint(new AjaxLoginAuthenticationEntryPoint()).accessDeniedHandler(ajaxAccessDeniedHandler());설정하실때 전자는 생성자를 만들고두번째는 왜 같은 방법으로 생성자를 만들지않고 등록을 하는건가요 ?-> .accessDeniedHandler(ajaxAccessDeniedHandler());이걸.accessDeniedHandler(new AjaxAccessDeniedHandler());이렇게 안하시는 이유가 있나요 ? 두번째 질문은 SecurityConfig 에서@Beanpublic AccessDeniedHandler accessDeniedHandler() {CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler();accessDeniedHandler.setErrorPage("/denied");return accessDeniedHandler;}이 등록되어있는데.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")).accessDeniedPage("/denied").accessDeniedHandler(accessDeniedHandler());이 두줄을 추가 하셨습니다. 우선적으로 여기서 첫번째 질문은.accessDeniedPage("/denied")랑accessDeniedHandler.setErrorPage("/denied");이게 같은 역할을 하는것이 아닌가요 ? 그리고 마지막으로.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))이 내용은 CustomAuthenticationFailureHandler 에 설정된setDefaultFailureUrl("/login?error=true&exception=" +errorMessage);super.onAuthenticationFailure(request,response, exception);이게 이미 처리하고 있던 내용 아닌가요 ? 마지막 질문은 .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")) 이건인가 예외로 생각하고 CustomAuthenticationFailureHandler 에 설정된 내용은 인증 내용이라고 생각하면 될까요 ?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
2023.08.10 기준 Spring Boot 3버전 대 Security Config 설정 파일 공유합니다.
@Configuration @EnableWebSecurity @RequiredArgsConstructor public class WebSecurity { private final UserService userService; private final BCryptPasswordEncoder bCryptPasswordEncoder; private final Environment environment; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(request ->{ request.requestMatchers(antMatcher("/actuator/**")).permitAll(); request.requestMatchers(antMatcher("/**")).permitAll();}) // .headers(header -> header.frameOptions( // frameOptionsConfig -> frameOptionsConfig.disable())) .apply(new MyCustomSecurity()); return http.build(); } public class MyCustomSecurity extends AbstractHttpConfigurer<MyCustomSecurity, HttpSecurity> { @Override public void configure(HttpSecurity http) throws Exception { AuthenticationManager authenticationManager = http.getSharedObject( AuthenticationManager.class); AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager, userService, environment); http.addFilter(authenticationFilter); } protected void configure2(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder); } } }해당 코드는 앞 내용까지 포함하여 설정이 적용된 버전입니다. 저같은 경우는 처음부터 mysql로 진행하여서 h2 콘솔을 사용하지 않아 frameOptions를 주석처리 하였으나, 혹여나 h2 콘솔 사용하시는 분은 주석 해제 후 사용하시면 되고, 23.08.10 기준으로 hasIpAddress는 사용 불가능합니다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
spring boot 3버전대에서 metrics에서 정보 안나오는 문제 해결
@Configuration @EnableAspectJAutoProxy public class MetricsConfig { @Bean public TimedAspect timedAspect(MeterRegistry registry) { return new TimedAspect(registry); } }해당 config 파일을 추가해주세요.
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
[해결완료] 로그인 인증 테스트코드 작성 질문입니다
안녕하세요 호돌맨 선생님!세션토큰 발급기능 추가를 초반에 보다가 로그인 관련 테스트를 직접 작성해보라고 하셔서 해봤는데 궁금한 점이 있어서 질문드립니다!작성한코드@Test @DisplayName("인증 테스트") void test11() throws Exception { // given Member member = Member.builder() .email("abc@naver.com") .password("1234") .build(); // UserRepository를 MemeberRepository로 이름 변경 했습니다. memberRepository.save(member); Login login = Login.builder() .email("abc@naver.com") .password("1234") .build(); String json = objectMapper.writeValueAsString(login); // expected mockMvc.perform(post("/auth/login") .contentType(APPLICATION_JSON) .content(json) ) .andExpect(status().isOk()) .andDo(print()); 결과query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2 원인JPA 에러라는 것을 검색을 통해서 알았습니다해결 방법 블로그 주소 : https://wakestand.tistory.com/943UserRepository에 작성한 findByEmailAndPassWord 메서드가 Optional로 되어 있는데 이 부분을 List로 변경해야할 것 같아서 다음과 같이 변경했습니다 변경된 코드UserRepositorypublic interface MemberRepository extends CrudRepository<Member, Long> { List<Member> findByEmailAndPassword(String email, String password); }AuthService@Service @RequiredArgsConstructor public class AuthService { private final MemberRepository memberRepository; public List<Member> signin(Login login) { List<Member> memberList = Optional.ofNullable(memberRepository.findByEmailAndPassword(login.getEmail(), login.getPassword())) .orElseThrow(() -> new InvalidSign()); return memberList; } } 위 처럼 Optional<Member가 아닌 List<Member>로 변경해서 테스트 로직을 성공하긴했습니다... 질문UserRepository의 Optional<Member>를 변경하지 않고 테스트 코드를 작성하는 방법이 있을까요??Optional에서 List로 변경했을 때 문제점은 없을까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
h2 경로를 못바꾸겠어요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.저번에 했을때 jdbc:h2:tcp://localhost/~/test 경로인데 이걸 못바꾸겠어요 새로운 경로로 다시만들고 싶은데 어떻게 바꾸는건지 시작화면에서 바꾸니깐 Database "C:/Users/ckehq/jpashop" not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-220] 90149/90149 에러만 떠요...
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
window11 / 23.08.09 기준 kafka connect 버전
window11 / 23.08.09 기준으로 kafka connect 버전을 7.1 버전으로 사용하시길 바랍니다.해당 강의의 6.1 버전에서 properties 경로를 못찾아서 버전업을 했더니 해결 했습니다.
-
해결됨실전! 스프링 데이터 JPA
1:N 양방향 매핑시에 컬렉션 필드 초기화가 안되는 문제..
안녕하세요. 강의 코드를 참고하며 1:N 양방향 매핑을 시도하고 있습니다.다른 테이블에서는 성공적으로 해서 정말 다른거 없이 똑같이 매핑해서 테스트를 진행중이었는데정말 이유를 모르겠는게 객체가 생성되면서 멤버 변수가 초기화가 되어야 하는데 되지 않아 null값이 들어가있고.null 값이 들어간 List에 add를 하려고 하니 NullPointerException이 나고 있습니다.같은 로직, 같은 OneToMany 매핑을 한 다른 엔티티 에서는 잘 되었는데 해당 부분에서 어떤 이유로 생성될때 멤버변수가 초기화가 되지 않는지 도무지 잘 모르겠습니다.. 이유를 아시는분 도와주시면 정말 감사하겠습니다.정상적으로 진행된 매핑 및 코드는 아래와 같습니다.@Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "dtype") @DiscriminatorValue("my") @Table(name="my_wallets") @Getter @Setter public class MyWallet { @Id @GeneratedValue @Column(name = "wallet_id") private Long id; private Integer balance=0; //cascade = Persist 속성을 명시해줌으로써, 영속성 전이를 사용하였음. //orphanRemoval = true 를 사용해서 고아 객체를 자동으로 제거 함. @OneToMany(mappedBy = "wallet", cascade = CascadeType.PERSIST,orphanRemoval = true) private List<Transactions> transactions = new ArrayList<>(); public void addTransactions(Transactions transaction){ this.transactions.add(transaction); transaction.setWallet(this); } ------------------------------------- @Entity @Table(name = "transactions") @Getter @Setter @ToString @AllArgsConstructor @NoArgsConstructor @Builder public class Transactions { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "transaction_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "wallet_id") @Setter private MyWallet wallet; private Long counterId; private Timestamp transactionDate; private String transactionType; private Integer amount; private String location; private Integer balance; private Boolean success; } ----------------------테스트 부분 Transactions t = Transactions.builder() .amount(100) .balance(200) .success(Boolean.TRUE) .build(); MyWallet m1 = createMyWallet(); m1.addTransactions(t); em.persist(m1);컴파일 에러도 없고, 정상적으로 h2 db에 들어가는것을 확인 했습니다.그런데 같은 로직으로 진행한 연관관계 메서드에서 오류가 발생했습니다.문제가 되는 코드들은 아래와 같습니다. import lombok.*; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity @Table(name = "article") @Getter @Setter @ToString @AllArgsConstructor @NoArgsConstructor @Builder public class Article { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "article_id") private Long id; private Long walletId; private Long imageId; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "transaction_id") private Transactions transaction; @OneToMany(mappedBy = "article",cascade = CascadeType.PERSIST, orphanRemoval = true) private List<Comments> comments = new ArrayList<>(); // List<Commnets> comments = new ArrayList 를 해주었음에도 null이 들어가있음. public void addComment(Comments comment){ //따라서 null 에 add 를 하려고 하니 NullPointerException이 발생합니다.. comments.add(comment); comment.setArticle(this); } } import lombok.*; import javax.persistence.*; import java.sql.Timestamp; @Entity @Table(name = "comments") @Getter @ToString @AllArgsConstructor @NoArgsConstructor @Builder @Setter public class Comments { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "comment_id") private Long commentId; @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "article_id") @Setter private Article article; private Long writerId; private String content; private Timestamp postedDate; } 이 아래는 실행해봤던 테스트 코드중 발생하는 위치의 코드입니다.. Article article = Article.builder() .imageId(99L) .walletId(1L) .imageId(-99L) .build(); em.persist(article); Comments comment = Comments.builder().content("컨텐츠1").writerId(123L).build(); System.out.println("comment = " + comment.toString()); em.persist(comment); article.addComment(comment); //이 부분이 문제..persist를 안해줘서 그런가 싶어서 앞뒤로 옮기며 확인해봤는데 여전히 필드 초기화가 되지 않아서 정말 의문입니다 제가 기본적으로 무엇을 놓치고 있는걸까요 ㅠㅠ 테스트 코드에서 무언가 잘못했을까 싶어 전체 코드도 남겨봅니다. import lombok.RequiredArgsConstructor; import org.apache.tomcat.jni.Address; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import java.awt.print.Book; @Component @RequiredArgsConstructor public class initDb { private final InitService initService; @PostConstruct public void init() { initService.doInit1(); // initService.doInit2(); } @Component @Transactional @RequiredArgsConstructor static class InitService { private final EntityManager em; public void doInit1() { Transactions t = Transactions.builder() .amount(100) .balance(200) .success(Boolean.TRUE) .build(); MyWallet m1 = createMyWallet(); m1.addTransactions(t); em.persist(m1); MoimWallet moim = createMoimWallet(1000); em.persist(moim); System.out.println("2차 테스트"); moim.setBalance(100); //Mywallet으로 업 캐스팅 ok MyWallet moim2 = createMoimWallet(2000); em.persist(moim2); User user = new User(null, m1, 1L, "ansik_id", "1234", "안식_name", "981212-121212", "010111", UserType.Parent, null); // user.getUsername("안식씨"); em.persist(user); WalletsAndMember wam = new WalletsAndMember(null, moim, user); em.persist(wam); WalletsAndMember wam2 = new WalletsAndMember(null, (MoimWallet) moim2, user); em.persist(wam2); Article article = Article.builder() .imageId(99L) .walletId(1L) .imageId(-99L) .build(); em.persist(article); Comments comment = Comments.builder().content("컨텐츠1").writerId(123L).build(); System.out.println("comment = " + comment.toString()); em.persist(comment); System.out.println("comment = " + comment.toString()); // comment.setArticle(article); article.addComment(comment); // article.getComments().add(comment); em.persist(article); em.flush(); em.clear(); } private static MyWallet createMyWallet() { MyWallet myWallet = new MyWallet(); return myWallet; } private static MoimWallet createMoimWallet(int amount) { MoimWallet moimWallet = new MoimWallet(); moimWallet.setTarget_amount(amount); return moimWallet; } } } 아래에 에러 로그를 남겨봅니다Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2023-08-10 00:59:32.985 ERROR 47056 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initDb': Invocation of init method failed; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920) ~[spring-context-5.3.28.jar:5.3.28] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.28.jar:5.3.28] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.13.jar:2.7.13] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.13.jar:2.7.13] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.13.jar:2.7.13] at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.13.jar:2.7.13] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.13.jar:2.7.13] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.13.jar:2.7.13] at team.ServerApplication.main(ServerApplication.java:12) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-2.7.13.jar:2.7.13] Caused by: java.lang.NullPointerException: null at team.entities.Article.addComment(Article.java:33) ~[classes/:na] at team.initDb$InitService.doInit1(initDb.java:74) ~[classes/:na] at team.initDb$InitService$$FastClassBySpringCGLIB$$48d5c178.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.28.jar:5.3.28] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.28.jar:5.3.28] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.28.jar:5.3.28] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.28.jar:5.3.28] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.28.jar:5.3.28] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.28.jar:5.3.28] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.28.jar:5.3.28] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.28.jar:5.3.28] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.28.jar:5.3.28] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.28.jar:5.3.28] at team.initDb$InitService$$EnhancerBySpringCGLIB$$3cdef9a7.doInit1(<generated>) ~[classes/:na] at team.initDb.init(initDb.java:22) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) ~[spring-beans-5.3.28.jar:5.3.28] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ~[spring-beans-5.3.28.jar:5.3.28] ... 23 common frames omitted Process finished with exit code 1