묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
HtmlEmailService 개발하다 생긴 의문입니다
HTML 인증 메일 전송하기 쪽 개발중에 궁금한게 생겼는데요회원 가입후 링크로 인증쪽 url의 토큰 뒤에 & 가 붙더라구요검색해서 확인해보니 & 의 경우 서버 스크립트에서 처리할 때 & 로 변환한다고 하더라구요 그래서 왜 자꾸 & 로 변환 될까 찾던 찰나에HtmlEmailService의 sendEmail 메서드에서 mimeMessageHelper.setText( String text, boolean html) 의 두번째 인자값이 false로 설정되어 있어 & 값이 생겼었던 것입니다.메일의 context 도 html 소스가 문자열 그대로 나오고 html 형태로 나왔었구요.true 로 설정하니 원만히 해결 되었는데이유가 궁금합니다... setText 메서드를 타고 들어가면 htmlText 를 MimePart로 변환해주는 메서드가 있는데정확히 알고 싶습니다..혹은 해당 메서드를 보고 이와 같은 문제를 맞딱드렸을때 알아내는 방법이나 노하우 같은게 있을까요 ?
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
자동키?가 없는 오라클에서 useGeneratedkey 사용하는 방법??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]오라클의 경우는 시퀀스로 증가하는 방법을 사용하는데, useGeneratedkey를 사용할 방법이 있을까요
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
[동시 세션 제어] invalidSessionUrl, expiredUrl API에 대하여
동시 세션 제어에서,invalidSessionUrl 경로를 지정하고 expiredUrl 경로를 지정하지 않았을 때 'This session has been expired' 메시지가 나오는데, 한 번 더 새로고침을 하면 정상적으로 invalidSessionUrl 경로로 가네요.?continue 경로로 302 응답 후 invalidSessionUrl 200 응답으로 되네요. 제 생각에는 버그가 아닐까 싶긴 합니다.
-
해결됨스프링 핵심 원리 - 기본편
섹션 7. 조회한 빈이 모두 필요할 때, List, Map
이렇게 한 상태에서 코드 돌리실 때 강의에서는 돌아가는데 제가 하니까 오류가 뜹니다...ㅠㅠ선생님께서도 fix하고 rate 모두 @Component 붙이셨고..강의에서 rate에서 @MainDiscountPolicy 제거하셨는데 어떻게 오류없이 돌아가는 건가요ㅠㅠ 왜 저만 오류가....이 강의에서 소스코드가 없어서 선생님하고 어느 부분이 다른지 확인하기도 어렵습니다ㅠㅠ어느 부분에서 잘못된 건지 확인 가능할까요...ㅠㅠhttps://drive.google.com/file/d/1zr_OjcriS2xs6HdrWQCUmuPCV4iAfGaw/view?usp=drive_link 혹은 소스코드를 받을 수 있으면 확인해보고싶습니다... @Test void findAllBean() { ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class); } static class DiscountService { private final Map<String, DiscountPolicy> policyMap; private final List<DiscountPolicy> policies; @Autowired public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) { this.policyMap = policyMap; this.policies = policies; System.out.println("policyMap = " + policyMap); System.out.println("policies = " + policies); }Error creating bean with name 'orderServiceImpl' defined in file [E:\study\core\build\classes\java\main\hello\core\order\OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [E:\study\core\build\classes\java\main\hello\core\order\OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:795) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93) at hello.core.autowired.AllBeanTest.findAllBean(AllBeanTest.java:22) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782) ... 17 more No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904) at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782) at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) at app//org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93) at app//hello.core.autowired.AllBeanTest.findAllBean(AllBeanTest.java:22) at java.base@21.0.3/java.lang.reflect.Method.invoke(Method.java:580) at java.base@21.0.3/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base@21.0.3/java.util.ArrayList.forEach(ArrayList.java:1596)
-
해결됨스프링 핵심 원리 - 기본편
섹션 7. 옵션처리
@Component class Ex1 { private final Member member; @Autowired(request = false) public Ex1(Member member) { this.mamber = member; } }@Aurowired(request = false)를 사용하면 생성자 호출이 되지 않으니까->Ex1은 스프링 빈으로 아예 등록 조차 안 되는 게 맞는 건가요? @NullableOptional<Member>만약 request = false를 사용하지않고,Nullable과 Optional을 사용하면 Ex1은 스프링 빈으로 등록되는 게 맞나요?? 그리고 수정자 주입같은 경우는@Component class Ex1 { private final Member member; @Autowired public void setEx1(Member member) { this.mamber = member; } }member가 스프링 빈에 등록되어 있지 않으면 Ex1을 스프링 빈에 member가 주입되지 않은 상태로 저장하고,member가 스프링 빈에 등록되어면 그때서야 Ex1에 자동으로 주입을 해주는 게 맞나요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
validation 폴더 및 validation-start 폴더 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 현재 섹션4 검증1을 듣고 있습니다.validation-start 파일을 갖고 와서 실행했을 때위와 같은 화면이 뜨는데요, 강의에 의하면 이렇게 떠야 합니다.메인 페이지에 오류가 있는것 같아, 파일을 수정해주시면 감사하겠습니다.
-
미해결스프링 핵심 원리 - 기본편
request 스코프 관련 문의
안녕하세요, 몇가지 질문이 있습니다. 선생님의 코드대로 쳤는데 제 인텔리제이에서는 왜 다음과 같은 에러가 발생하는지 모르겠습니다.왜 LogDemoController가 static 컨텍스트라고 떠서 이런 에러가 발생하는지 모르겠습니다.제가 봤을땐 static이 아닌데 말이죠 (MyLogger, Controller, Service 모두 static은 없음)여기까지의 소스 코드를 1차 첨부합니다. (에러 발생 코드)package hello.core.common; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import java.util.UUID; @Component @Scope(value="request") public class MyLogger { private String uuid; // unique id private String requestURL; public void setRequestURL(String requestURL){ this.requestURL = requestURL; } public void log(String message){ System.out.println("[" + uuid + "] " + "[" + requestURL + "]" + message); } @PostConstruct public void init(){ uuid = UUID.randomUUID().toString(); System.out.println("[" + uuid + "] " + "[" + requestURL + "] request scope bean create : " + this); } @PreDestroy public void close(){ System.out.println("[" + uuid + "] " + "[" + requestURL + "] request scope bean close : " + this); } /* 로그를 출력하기 위한 클래스 request 스코프로 지정했으며, HTTP 요청당 하나씩 생성되고, HTTP 요청이 끝나는 시점에 소멸된다. 이 빈이 생성되는 시점에 자동으로 @PostConstruct 초기화 메서드를 사용해서 uuid를 생성해서 저장해둔다. 이 빈은 HTTP 요청 당 하나씩 생성되므로, uuid를 저장해두면 다른 HTTP 요청과 구분할 수 있다. requestURL은 빈이 생성되는 시점에는 알 수 없으므로 외부에서 setter로 입력받는다. */ }package hello.core.web; import hello.core.common.MyLogger; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequiredArgsConstructor public class LogDemoController { private final LogDemoService logDemoService; private final ObjectProvider<MyLogger> myLoggerProvider; // 스프링 컨테이너가 뜨면서 의존관계 주입을 해야하는데 mylogger는 request scope이라 아직 고객 요청이 없어서 에러 @RequestMapping("log-demo") @ResponseBody public String logDemo(HttpServletRequest request){ String requestURL = request.getRequestURL().toString(); // 고객이 요청한 url을 받을 수 있음 MyLogger myLogger = myLoggerProvider.getObject(); // 주입 시점에 주입 받을 수 있음 myLogger.setRequestURL(requestURL); myLogger.log("controller test"); LogDemoService.logic("testId"); return "OK"; } }package hello.core.web; import hello.core.common.MyLogger; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class LogDemoService { private final ObjectProvider<MyLogger> myLoggerProvider; public void logic(String id) { MyLogger myLogger = myLoggerProvider.getObject(); myLogger.log("service id = " + id); } }어쨋든 이 문제를 해결하지 않으면 소스 코드 실행이 되지 않습니다. 따라서 intelliJ 가이드에 따라 static으로 만들어주고 실행을 하면 또 에러가 발생합니다.private final ObjectProvider<MyLogger> myLoggerProvider;위 구문 초기화를 하라는 가이드에 = Null을 해주면 소스 코드 실행 시 (디버깅 결과) myLoggerProvider.getObject() 에서 널포인트 익셉션이 터집니다.여기까지 상황의 코드를 2차 첨부합니다.package hello.core.web; import hello.core.common.MyLogger; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequiredArgsConstructor public class LogDemoController { private final LogDemoService logDemoService; private final ObjectProvider<MyLogger> myLoggerProvider; // 스프링 컨테이너가 뜨면서 의존관계 주입을 해야하는데 mylogger는 request scope이라 아직 고객 요청이 없어서 에러 @RequestMapping("log-demo") @ResponseBody public String logDemo(HttpServletRequest request){ String requestURL = request.getRequestURL().toString(); // 고객이 요청한 url을 받을 수 있음 MyLogger myLogger = myLoggerProvider.getObject(); // 주입 시점에 주입 받을 수 있음 myLogger.setRequestURL(requestURL); myLogger.log("controller test"); LogDemoService.logic("testId"); return "OK"; } }package hello.core.web; import hello.core.common.MyLogger; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class LogDemoService { private static final ObjectProvider<MyLogger> myLoggerProvider = null; public static void logic(String id) { MyLogger myLogger = myLoggerProvider.getObject(); myLogger.log("service id = " + id); } } 어떻게 해결해야할까요? 제가 잘못 타이핑한 부분이 있다면 말씀 부탁드립니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
강의소스코드
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]수업 자료 소스 코드를 다운받았습니다.여기서 서블렛에 대한 소스코드를 인텔리제이로 연결해서보고싶은데인텔리제이 들어가서 오픈프로젝트하고 build.gradle 했는데 이런식으로 뜨는데 어떻게 해야할까요?ㅠ
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Controller 에서 Service 로 넘기는 파라미터에도 DTO를 사용할 수 있을까요?
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]선생님 강의를 거의 다 완강하고 혼자 프로젝트를 진행중에 궁금증이 생겨 질문 남깁니다. 클린코드 원칙에 따르면 메서드의 파라미터는 적으면 적을 수록 좋다고 배웠습니다.만약 컨트롤러에서 서비스 메서드를 호출할때,필요한 파라미터 값이 많을때는 컨트롤러에서 DTO를 생성하여서비스객체에 전달하는 방법도 고려해볼 수 있을까요? DTO는 컨트롤러가 웹 호출을 받는 경우에만 사용해 왔는데 이런 방식의 DTO 활용도 가능한지 질문드립니다.
-
미해결스프링 핵심 원리 - 기본편
싱글톤 패턴 문제점
싱글톤 패턴의 문제점중 하나로 클라이언트가 구체 클래스에 의존해서 DIP와 OCP원칙을 위반할 수 있다고설명이 되어 있는데 궁금한 부분이 여기서 말하는 클라이언트가 아래와 같이 강의 중에 설명한 코드 중private static final SingletonService instance = new SingletonService()를 의미하는건지혹은 두 번째 코드에서 SingletonService singletonService1 = SingletonService.getInstance()과 같이 SingletonService 객체에서 객체를 가져오는 것을 의미하는 건가요? 그리고 강사님께서 싱글톤 패턴을 테스트에 위치하여 작성하였고 해당 SingletonService 클래스의 싱글톤을 구현한 코드를 해당 클래스 안에 작성하셨는데 스프링을 사용하지 않는다는 가정하에 싱글톤으로 컨테이너 객체를 관리할 때 SingletonService는 인터페이스고 해당 인터페이스를 구현하는 구현 클래스에 싱글톤 구현부들 작성하는게 맞을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
h2 데이터베이스 설정 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:116) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:290) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.boot.model.relational.Database.<init>(Database.java:45) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.8.jar:6.1.8] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390) ~[spring-orm-6.1.8.jar:6.1.8] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.1.8.jar:6.1.8] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.8.jar:6.1.8] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366) ~[spring-orm-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) ~[spring-beans-6.1.8.jar:6.1.8] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.0.jar:3.3.0] at jpabook.jpashop.JpashopApplication.main(JpashopApplication.java:16) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[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:568) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.3.0.jar:3.3.0]2024-06-12T10:54:03.045+09:00 ERROR 26788 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)2024-06-12T10:54:03.047+09:00 WARN 26788 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)2024-06-12T10:54:03.061+09:00 INFO 26788 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]2024-06-12T10:54:03.086+09:00 INFO 26788 --- [ restartedMain] .s.b.a.l.ConditionEvaluationReportLogger : Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.2024-06-12T10:54:03.135+09:00 ERROR 26788 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed제가 컴퓨터 재부팅하고 JpashopApplicaton을 실행했을 때 다음과 같이 에러가 떠서 h2 데이터베이스 설정이 안됐나 싶어서 설정하려 했는데 h2에서 다음과 같은 에러가 발생했다고 하네요... 이거 Chat GPT한테 물어보면 application.yml을 다시 설정하라 하는데 뭔가 건드리면 안될 것 같아서 그런데 어떻게 해결하면 좋을지 질문 드리고자 합니다.
-
미해결스프링 핵심 원리 - 고급편
스프링 문의드립니다.
해결함 !
-
미해결스프링 시큐리티 OAuth2
OAuth2 로그인 구현 - Oauth 2.0 User 모델 소개 issuer-uri에러
섹션 7OAuth2 로그인 구현 - Oauth 2.0 User 모델 소개(2)진행시 설정시 에러가 납니다uli 클릭하면realm: "oauth2",public_key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqFd5+xNaJoQzccdweHH4hxMOOirdHcbGx7tAkl7YWFAD0kBpVmpFN3sWaz3T3CLa0zSULmEWuepEkf/T376JKs+opBRb8pfnDSvvq1va4UXhw5j1mMgN8a6kME2TfM4cd2XnnT9huTIJ2+4nTYPTwKhYd+KvgB1ruzUe4ApMw0injfbsyufS17bhGtHYn4Ysq7THWsOAPVQ+FMYd8e1T4tfY1jkQg68UYB43dHST34y0JWkStPowP80qLMbsPvJ4JrOCzSGk08sBvmd6Fo1KD9RAqZyGvQFXEyo1Y5jVcKGCgwin0ijQBCKhRpHmWGlmyamrW6fsgAnAJH+clUdAwQIDAQAB",token-service: "http://localhost:8080/realms/oauth2/protocol/openid-connect",account-service: "http://localhost:8080/realms/oauth2/account",tokens-not-before: 0}이렇게 잘나옵니다. implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test'spring: application: name: inf_oauth2 security: oauth2: client: registration: keycloak: authorization-grant-type: authorization_code client-id: oauth2-client-app client-name: oauth2-client-app client-secret: 90GVrQtfYCp1u9cc0VAJNFiY8ZzCyjHD redirect-uri: http://localhost:8081/login/oauth2/code/keycloak client-authentication-method: client_secret_basic scope: openid, profile, email provider: keycloak: issuer-uri: http://localhost:8080/realms/oauth2 authorization-uri: http://localhost:8080/realms/oauth2/protocol/openid-connect/auth jwk-set-uri: http://localhost:8080/realms/oauth2/protocol/openid-connect/certs token-uri: http://localhost:8080/realms/oauth2/protocol/openid-connect/token user-info-uri: http://localhost:8080/realms/oauth2/protocol/openid-connect/userinfo user-name-attribute: preferred_username org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexContoller': Unsatisfied dependency expressed through field 'clientRegistrationRepository': Error creating bean with name 'clientRegistrationRepository' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.class]: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method 'clientRegistrationRepository' threw exception with message: Unable to resolve Configuration with the provided Issuer of "http://localhost:8080/realms/oauth2" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessorAutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:787) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessorAutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:767) ~[spring-beans-6.1.6.jar:6.1.6] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRegistrationRepository' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.class]: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method 'clientRegistrationRepository' threw exception with message: Unable to resolve Configuration with the provided Issuer of "http://localhost:8080/realms/oauth2" at java.base/java.util.HashMap.forEach(HashMap.java:1421) ~[na:na] at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper.asClientRegistrations(OAuth2ClientPropertiesMapper.java:64) ~[spring-boot-autoconfigure-3.2.5.jar:3.2.5] at org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration.clientRegistrationRepository(OAuth2ClientRegistrationRepositoryConfiguration.java:49) ~[spring-boot-autoconfigure-3.2.5.jar:3.2.5] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[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:568) ~[na:na] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.6.jar:6.1.6] ... 34 common frames omitted
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
필터가 3번 호출되야 되는거 아닌가요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]1. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생) 2. WAS /error-page/500 다시 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(/error-page/ 500) -> View이렇게 오류가 나면 필터가 적용된다고 써져있는데 그럼 맨처음에 요청이 들어와서 컨트롤러로 갈 때도 필터가 적용되니까 총 3번 REQUEST [4f746f4d-c301-44a3-ab12-793ecca80e91][REQUEST][/error-ex]RESPONSE [4f746f4d-c301-44a3-ab12-793ecca80e91][REQUEST][/error-ex]이부분이 출력이 되야되는거 아닌가요? 1. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)이 과정에서는 필터가 호출이 안되는 건가요?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
양방향 연관관계의 필요성, 단방향 연관관계 시 fetch join
[질문 내용]우선 단방향 연관관계를 적용하고 꼭 필요한 경우에 양방향 연관관계를 사용하라는 내용을 적용해보다가 이해가 안되는 부분이 생겨서 질문남깁니다. Team과 Member로 양방향 연관관계를 적용한다고 생각해보면 다른 질문의 답변을 봤을 때 Team을 조회할 때 Member가 거의 같이 조회가 되는 경우와 fetch join으로 조회 시 양방향 연관관계를 사용하여 더 편리하게 조회할 때 사용한다는 답변을 봤습니다. (제대로 이해한 것인지는 모르겠습니다.) 그래서 테스트를 해봤습니다.@Test void 멤버목록과_함께_팀조회() { Team team = new Team("teamA"); entityManager.persist(team); Member member = new Member("m1", 0, team); Member member2 = new Member("m2", 0, team); entityManager.persist(member); entityManager.persist(member2); entityManager.flush(); entityManager.clear(); System.out.println("====테스트 1 양방향 연관관계==="); Team findTeam = teamJpaRepository.findById(team.getId()).get(); List<Member> members = findTeam.getMembers(); for (Member member1 : members) { System.out.println("member1 = " + member1.getUsername()); } entityManager.flush(); entityManager.clear(); System.out.println("===테스트 2 fetch join 양방향 연관관계 사용=="); Team findTeam2 = teamRepository.findTeamWithMembersById(team.getId()).get(); List<Member> members2 = findTeam2.getMembers(); for (Member member1 : members2) { System.out.println("member1 = " + member1.getUsername()); } entityManager.flush(); entityManager.clear(); System.out.println("===테스트 3 fetch join 그냥 엔티티 사용=="); Team findTeam3 = teamRepository.findTeamWithMemberById(team.getId()).get(); List<Member> members3 = findTeam3.getMembers(); for (Member member1 : members3) { System.out.println("member1 = " + member1.getUsername()); } } public interface TeamRepository extends JpaRepository<Team, Long> { @Query("select t from Team t join fetch t.members") Optional<Team> findTeamWithMembersById(Long id); @Query("select t from Team t join fetch Member m") Optional<Team> findTeamWithMemberById(Long id); }테스트 1의 경우 두개의 쿼리가 나가는 것을 확인했습니다. selectt1_0.team_id,t1_0.create_by,t1_0.created_date,t1_0.last_modified_by,t1_0.last_modified_date,t1_0.namefromteam t1_0wheret1_0.team_id=? selectm1_0.team_id,m1_0.member_id,m1_0.age,m1_0.create_by,m1_0.created_date,m1_0.last_modified_by,m1_0.last_modified_date,m1_0.usernamefrommember m1_0wherem1_0.team_id=? 테스트 2의 경우 한개의 쿼리만 나가는 것을 확인했습니다.selectt1_0.team_id,t1_0.create_by,t1_0.created_date,t1_0.last_modified_by,t1_0.last_modified_date,m1_0.team_id,m1_0.member_id,m1_0.age,m1_0.create_by,m1_0.created_date,m1_0.last_modified_by,m1_0.last_modified_date,m1_0.username,t1_0.namefromteam t1_0joinmember m1_0on t1_0.team_id=m1_0.team_id 테스트 3의 경우 오류가 났습니다. 위의 테스트 1(getMembers로 접근), 테스트2(fetch join)의 경우 쿼리의 개수로 봤을 때 테스트 2를 사용하는 게 더 좋은 것 같은데 맞을까요?테스트 3은 단방향인 경우 팀과 멤버를 같이 조회를 어떻게 해야되나요?양방향 연관관계가 필요한 경우가 뭔가요?원래 api 설계할 때 team, member를 각각 조회하는 경우만 만들었었는데, team과 member가 같이 조회되는 api를 만드는 경우도 있나요? (team/{id}, member/{id} 와 같은 경우만 만들어봤습니다.)
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
다중 DB 설정 및 트랜잭션 공유 설정
안녕하세요!마이바티스에서 MS-SQL, ORACLE 두 개의 데이터 소스를 설정하는 방법과MS-SQL, ORACLE 각각의 트랜잭션을 서비스레이어에서 같이 사용하는 방법이 있을까요?알려주시면 감사합니다 ㅠ @Service public class MyService { @Autowired private OracleRepository oracleRepository; @Autowired private SqlServerRepository sqlServerRepository; @Transactional public void update() { oracleRepository.update() sqlServerRepository.update() //에러 발생 시 ms-sql 트랜잭션, oracle 트랜잭션 롤백 방법 } }
-
미해결
연관관계 메서드에 대해 질문드립니다.
@Entity @Table(name = "orders") @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "delivery_id") private Delivery delivery; //배송정보 private LocalDateTime orderDate; //주문시간 @Enumerated(EnumType.STRING) private OrderStatus status; //주문상태 [ORDER, CANCEL] //==연관관계 메서드==// public void setMember(Member member) { this.member = member; member.getOrders().add(this); // Member 엔티티 부분 : private List<Order> orders = new ArrayList<>(); } public void addOrderItem(OrderItem orderItem) { orderItems.add(orderItem); // OrderItem 엔티티 부분 : private Order order; orderItem.setOrder(this); } public void setDelivery(Delivery delivery) { this.delivery = delivery; // Delibery 엔티티 부분 : private Order order; delivery.setOrder(this); } member.getOrders().add(this) -> addOrderItem과 setDelivery에서는 setOrder(this)로 연관관계를 설정해줬는데, 왜 setMember 메소드에서만 getOrders().add(this)로 연관관계를 설정한 것인가요? Member 엔티티의 orders메소드가 List라 그런 것인가요? setMember에서는 같은 List임에도 불구하고 this.member = member라고 했는데, 왜 여기서는 add(orderItem)으로 연관관계를 설정한 것인가요? orderItems가 List라서 그런 것인가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
오류 org.springframework.context.NoSuchMessageException: No message found under code 'hello' for locale 'null'.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 강의를 듣던중에 MessageTestSourceTest 부분에서 오류 터져서 커뮤니티랑 구글링을 해보니 다들 한글이 깨졌다고 하더라고요 그래서 저도 utf8로 해도 똑같은 오류가 나더라구요.그런데 여기서 ItemServiceApplication.java 에 ```java@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; }```을 남기니깐 테스트를 통과하더라고요 혹시 어떤 문제인지 알고 있으시나요? ㅠㅠ
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
members 500 오류 힘드네요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]찾아보고 했는데 계속 오류 뜨는데 어떻게해야할까요
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
PRG addFlashAttribute
@GetMapping("/join") public String addAdminForm(@ModelAttribute("form") AddAdminForm form) { return "admin/admins/join"; } @PostMapping("/join") public String join(@Valid @ModelAttribute("form") AddAdminForm form, BindingResult bindingResult, RedirectAttributes redirectAttributes) { //회원가입 로직 Integer adminId = adminService.join(form); redirectAttributes.addFlashAttribute("adminId", adminId); return "redirect:/admin/admins/join/complete"; } @GetMapping("/join/complete") public String joinComplete(@ModelAttribute(name = "adminId") Integer adminId, Model model) { NewMemberInfo newAdminInfo = adminService.getNewAdminInfo(adminId); model.addAttribute("admin", newAdminInfo); return "admin/admins/join_complete"; }안녕하세요 회원가입이 완료되면 redirect 시켜서 회원가입 완료페이지로 이동시켰습니다. 이때 url을 /join/complete로 하기위해 addFlashAttribute로 adminId를 전달했습니다. 이후 회원가입 완료 페이지에서 로그인 하러 이동버튼을 눌러 로그인페이지로 이동한뒤 뒤로가기로 /join/complete에 다시 들어오게 되면 전달되는 adminId가 없어서 오류가 발생합니다. addFlashAttribute외에 다른 방법으로 adminId를 전달할수있나요?