========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] Spring이 런타임에서는 상품을 잘 저장하고, 불러오는 것도 정상적입니다. 그런데 스프링을 Re-Run 하게 되면, 상품이 전부 사라지네요. ddl-auto: create를 update로 바꿨더니 데이터가 안 사라지네요. 이거 말고 다른 이유는 없는 건가요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요!! 강의를 보면서 팩토리 메서드에 대해 궁금증이 몇가지 생겼는데 구글링을 해봐도 잘 나오지 않아서 질문 올립니다🥲 1. 팩토리 메서드를 사용하는 기준이 있을까요? 생성자를 통해 객체를 생성하지 않고, 팩토리 메서드를 사용하는 경우 이름을 가질 수 있다, 하위 타입 객체를 반환할 수 있다 등등의 장점이 있고, 이에 반해 몇몇 단점도 있는것 같은데 단순히 팩토리 메서드 내부에서 생성자만 호출하는 경우에도 실무에서는 팩토리 메서드를 웬만하면 다 사용하는 편인가요?? 생성자 대신 팩토리 메서드를 사용하여 객체를 생성하는 상황이나 기준이 있는지 궁금합니다! 2. 팩토리 메서드를 사용하는 경우 프로젝트에서 네이밍 규칙을 어떻게 가져가는 것이 좋을까요? 강의를 듣고 복습하면서 Order와 같이 연관 관계들이 얽혀있는 팩토리 메서드는 createOrder와 같은 좀 더 의미있는 이름을 사용하고, 그냥 단순히 객체만 생성하는 경우에는 of를 사용해서 실습을 해보았습니다! 실무에서 프로젝트를 진행하면 위와 같이 어떠한 룰을 만들어서 사용하시는지, 아니면 하나의 이름으로 통일해서 가져가시는지 궁금합니다 ㅎㅎ 감사합니다 😀
현재 그룹 조회 API를 구현하고 있습니다. 메신저 앱 처럼 그룹 조회시 그룹 아이디, 그룹 이름, 그룹 이미지, 그룹에 속해있는 멤버들 (컬렉션)을 조회해 와야합니다. 여기서 강의의 V3 내용처럼 1 + N 문제를 해결하기 위해서 다음과 같이 페치 조인을 사용하여 쿼리문을 작성하였습니다. TeamRepository.java @Transactional(readOnly = true) public interface TeamRepository extends JpaRepository<Team, Long> { @Query("select distinct t from Team t" + " join fetch t.id id" + " join fetch t.groupName gn" + " join fetch t.imageUrl iu" + " join fetch t.teamMembers tm" + " join fetch tm.member m" + " where tm.id = :id") List<SearchGroupResponse> findGroupInfoWithMembers(@Param("id") Long id); } `Team.java` @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Team extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @Column(length = 30) private String groupName; @Lob private String imageUrl; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "place_id") private Place place; @OneToMany(mappedBy = "team", cascade = CascadeType.ALL) private final List<TeamMember> teamMembers = new ArrayList<>(); private LocalDateTime date; } TeamMember.java @Entity @Getter @Table(name = "GroupMember") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class TeamMember extends BaseEntity { @ManyToOne(fetch = LAZY) @JoinColumn(name = "member_id") private Member member; @ManyToOne(fetch = LAZY) @JoinColumn(name = "team_id") private Team team; @Column(length = 100) private String curLocate; private char arrived; public TeamMember(Member member, Team team) { this.member = member; this.team = team; } } 강의 V3-1 과 같이 컬랙션 데이터는 지연 로딩과 BatchSize를 적용하여 성능 최적화를 해줘야 된다고 배웠지만 일단은 V3를 적용해 보고 개선해 보고자 이렇게 코드를 작성해 보았습니다. 하지만 다음과 같은 에러가 발생하였고 이를 해결하고자 여러 구글링을 해보았지만 해답을 찾지 못하여 질문 남겨봅니다. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'promiseController' defined in file [/Users/sanha/SpringStudy/promisor/out/production/classes/promisor/promisor/domain/promise/api/PromiseController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'promiseService' defined in file [/Users/sanha/SpringStudy/promisor/out/production/classes/promisor/promisor/domain/promise/service/PromiseService.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teamRepository' defined in promisor.promisor.domain.team.dao.TeamRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! Reason: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)!; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.15.jar:5.3.15] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.15.jar:5.3.15] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.3.jar:2.6.3] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.6.3.jar:2.6.3] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414) ~[spring-boot-2.6.3.jar:2.6.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-2.6.3.jar:2.6.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.6.3.jar:2.6.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.6.3.jar:2.6.3] at promisor.promisor.PromisorApplication.main(PromisorApplication.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:64) ~[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:564) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.6.3.jar:2.6.3] Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'promiseService' defined in file [/Users/sanha/SpringStudy/promisor/out/production/classes/promisor/promisor/domain/promise/service/PromiseService.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teamRepository' defined in promisor.promisor.domain.team.dao.TeamRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! Reason: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)!; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.15.jar:5.3.15] ... 24 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'teamRepository' defined in promisor.promisor.domain.team.dao.TeamRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! Reason: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)!; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.15.jar:5.3.15] ... 38 common frames omitted Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! Reason: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)!; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! at org.springframework.data.repository.query.QueryCreationException.create(QueryCreationException.java:101) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:106) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:94) ~[spring-data-commons-2.6.1.jar:2.6.1] at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na] at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) ~[na:na] at java.base/java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1056) ~[na:na] at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:na] at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na] at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na] at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na] at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na] at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:96) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:86) ~[spring-data-commons-2.6.1.jar:2.6.1] at java.base/java.util.Optional.map(Optional.java:258) ~[na:na] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:86) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:364) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:322) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:328) ~[spring-data-commons-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.15.jar:5.3.15] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.15.jar:5.3.15] ... 49 common frames omitted Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List promisor.promisor.domain.team.dao.TeamRepository.findGroupInfoWithMembers(java.lang.Long)! at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:96) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:66) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:51) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:163) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:252) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:87) ~[spring-data-jpa-2.6.1.jar:2.6.1] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:102) ~[spring-data-commons-2.6.1.jar:2.6.1] ... 71 common frames omitted Caused by: java.lang.NullPointerException: Cannot invoke "org.hibernate.hql.internal.ast.tree.FromElement.setAllPropertyFetch(boolean)" because "fromElement" is null at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:431) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3990) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3776) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3654) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:737) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:593) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:330) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:278) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:636) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:748) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:114) ~[hibernate-core-5.6.4.Final.jar:5.6.4.Final] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[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:564) ~[na:na] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) ~[spring-orm-5.3.15.jar:5.3.15] at com.sun.proxy.$Proxy139.createQuery(Unknown Source) ~[na:na] at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:90) ~[spring-data-jpa-2.6.1.jar:2.6.1] ... 77 common frames omitted
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. 강의내용대로 @Transactional 넣고 스프링부트띄워서 테스트를 돌리면 rollback이 바로되는게 아니라 좀 지나서 되는것 같더라구요 회원가입 테스트 돌리고 디비에서 member조회 해보면 인서트가 되어있고 한번더 조회하면 그때 사라지더라구요 그것 때문에 회원가입과 중복회원 따로 돌리면 되긴하는데 전체 테스트를 돌리면 중복회원예외에서 실패가 납니다. 어떻게 해야될까요..?
제 환경은 Mac에 Zsh을 설치하여 사용하고 있는데 위와 같은 에러가 발생하는 문제가 존재하였습니다. 해당 문제는 간단하게 해결할 수 있습니다. JobParmeters로 넘길 인자를 따옴표(')로 감싸서 던지면 해결됨을 확인할 수 있습니다. 이런 식으로 정상적으로 나옴을 확인할 수 있었습니다. 동일한 문제가 발생한 분들 참고하시면 도움이 되실 것 같습니다.
안녕하세요 영한님. 올려주신 spring 강의부터 jpa까지 거의 다 듣고 배운것을 활용해서 토이 프로젝트 만들고 있습니다. web api 설계시에 궁금한것이 있어 문의드립니다. 만약 parents 있고 children이 존재합니다. parent와 children은 1대N 관계입니다. 제가 처음 백엔드 api 설계했을때 아래처럼 설계했습니다. POST /parents : parents 리소스가 생성됩니다. POST /parents/{id}/children : parent와 연관된 children 이 생성됩니다. 설계를 마치고 프론트엔드에서 해당 api를 이용해서 등록하려했습니다. 여기서 궁금한것이 생겼습니다. 아래 두 방식중 어떤것이 좋은것인지 잘모르겠습니다. 1. 프론트에서 한번의 Post 요청으로 parents와 childrens list를 모두 생성합니다. request body 예시: { parent: "..." children:[ "...", "..." ] } 백엔드에서 parent정보로 parent 리소스를 만들고 만들어진 parent의 id와 body에 있는 children 리스트로 children 리소스를 생성합니다. 2. 프론트에서 POST /parent와 POST /parent/{id}/children을 각각 요청합니다. 먼저 POST /parents 요청을 보내고 응답값에서 parents id를 받아 children 갯수만큼 POST /parents/{id}/childrens 요청을 합니다.(이럴경우 요청수는 1+N이 겠네요). 1번과 2번 방식중에 어떤 방법이 나은지 잘 모르겠습니다. 제가 생각한 각각의 장단점입니다. 1번의 장점 : 하나의 요청에 모든 정보가 들어있어 요청 처리중 에러 발생시 기존에 저장된 정보도 롤백이 가능하다는 장점이 있을것같습니다. 또한 request도 한번이면 됩니다. 1번의 단점 : api가 직관적이지 않은것같습니다. 클라이언트는 POST /parents를 사용하면 parents 리소스가 생길것으로 예상합니다. 하지만 해당 요청으로 children이 생길것이라는것은 문서를 봐야합니다. 또한 유연하지 않다고 생각합니다(클라이언트마다 구현방식이 다를것이므로) 2번의 장점 : api가 직관적입니다. 유연합니다. 클라이언트가 구현방식을 바꾸더라도 백엔드의 api를 바꾸지 않아도 될것같습니다. 2번의 단점 : 클라이언트쪽에서 여러번 api를 호출해야합니다. 요청 도중에 에러가 발생할 경우 parents는 등록되고 children은 등록이 안될수도 있습니다. 둘중에 어떤것 방식을 실무에서 사용하나요? 2번으로 마음이 좀 기울긴하는데, 위에 적히 단점들이 걸리네요.. 그리고 클라이언트쪽에서 N개의 children를 모두 등록하고 싶을때 body에 list를 담아서 post /children 전부를 한번에 보내서 처리할수있게 api를 만드는게 좋은것인가요? (하나의 요청으로 여러개의 리소스 생성, 백엔드에서 리스트를 순회하면서 저장) 아니면 클라이언트쪽에서 list를 순회하면서 N번 post 요청 하게 만드는것이 좋은가요?( 하나의 요청으로 하나의 리소스생성, 대신 여러번 호출) 긴글 읽어주셔서 감사합니다.
왜 에러가 나오는지 모르겠습니다. Controller에서 Mapping 할 때 그냥 hello로 하면 404가 나오고 /hello 로 하게 되면 500 에러가 나오게 됩니다. 022-05-04 12:15:15.062 ERROR 5008 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [hello!], template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause org.thymeleaf.exceptions.TemplateInputException: Error resolving template [hello!], template might not exist or might not be accessible by any of the configured Template Resolvers at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE] at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1401) ~[spring-webmvc-5.3.19.jar:5.3.19] at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1145) ~[spring-webmvc-5.3.19.jar:5.3.19] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) ~[spring-webmvc-5.3.19.jar:5.3.19] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.19.jar:5.3.19] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.19.jar:5.3.19] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.19.jar:5.3.19] at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.62.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.19.jar:5.3.19] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.62.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.19.jar:5.3.19] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.19.jar:5.3.19] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.19.jar:5.3.19] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.19.jar:5.3.19] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.19.jar:5.3.19] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.19.jar:5.3.19] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.62.jar:9.0.62] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
실무에서 DB 를 사용한다고 하면 배치나 데이터 파이프라인 등이 아닌 OLTP 환경에서는 절대 오프셋 기반의 페이징을 쓰면 안되지 않나요? 우선 페이징 도중에 다른 클라이언트에 의해 실시간으로 데이터가 삽입/삭제가 일어나 중복된 데이터가 보여지거나 중간 데이터 누락이 발생할 수도 있기 때문에 문제가 될 것이고, 성능의 관점에서도 SQL 쿼리에서 OFFSET 문의 경우 index seek 과정에서 바로 페이지의 첫 데이터를 찾아가는것이 아니라 불필요하게 맨 처음 인덱스부터 offset 사이즈만큼 스캔한 뒤에 limit 만큼 가져오는 것이기 때문에 scalable 않지만, 커서 기반의 페이징의 경우 데이터의 양이 많아지더라도 where 절을 통해 index seek 과정에서 바로 커서에 해당하는 인덱스를 찾아가서 page size 만큼의 데이터만 스캔하면 되기 때문에 실무에서 굳이 오프셋 기반의 페이징을 쓸 이유가 없다. 라고 이해하면 맞을까요? 물론 페이징 대상이 되는 데이터의 수 자체가 매우 적거나 유저가 많은 페이지를 탐색하지 않는다면 큰 문제가 되지 않을 수도 있지만, 커서 기반의 페이징을 구현하는것이 특별이 어려운 것도 아니고 굳이 오프셋 기반의 페이징을 사용할 필요가 있나 궁금했습니다!
안보일 까봐 복사했습니다. 2022-05-02 07:18:24.438 INFO 1 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8888 2022-05-02 07:18:24.772 INFO 1 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available 2022-05-02 07:18:24.773 WARN 1 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Could not locate PropertySource: I/O error on GET request for "http://localhost:8888/capstone-cell-service/default": Connection refused; nested exception is java.net.ConnectException: Connection refused 2022-05-02 07:18:24.781 INFO 1 --- [ main] c.e.c.CapstoneCellServiceApplication : No active profile set, falling back to 1 default profile: "default" * 그래서 라고생각하는데 회원가입은 제대로 진행되는 반면, 로그인 시도 시 , 2022-05-02 10:10:21.244 ERROR 1 --- [o-auto-1-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.lang.NumberFormatException: Cannot parse null string at java.base/java.lang.Long.parseLong(Long.java:685) ~[na:na] at java.base/java.lang.Long.parseLong(Long.java:847) ~[na:na] at com.example.capstoneuserservice.security.AuthenticationFilter.successfulAuthentication(AuthenticationFilter.java:71) ~[classes!/:1.0] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:232) ~[spring-security-web-5.5.5.jar!/:5.5.5] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.5.5.jar!/:5.5.5] 오류가 발생하면서 못읽어오는 듯한 모습을 보여주는것 같습니다.. 안녕하세요 강사님. 강사님 강의듣고 프로젝트 진행중에 있는 학생입니다. 수업을 듣고 로컬에서 진행하는 것이 아닌 ec2에서 진행하고있습니다. docker hub에 push한 image를 ec2 서버로 접속 후 pull 하여 백그라운드로 run하여 구성하였습니다. 그런데 회원가입은 진행이 잘 됩니다만 로그인 실행시 long에 들어가는 token.expiration.time 이었나 null로 들어와서, 왠지 봤더니 아예 github에 public으로 존재하는 application.yml 파일을 읽어 오지 못하고있는것 같습니다. 저의 application.yml이 존재하는 깃허브 주소는 https://github.com/KimTaeKang57/capstone-cloud-config.git 입니다만. WARN 오류를 잘 보면 연결을 하지못하는 것같은데요, user-service의 bootstratp.yml 파일 내용은 spring : cloud : config : uri : http://127.0.0.1:8888 name : application 다음과같고, config-server의 application.yml은 spring : application : name : capstone-configure-service cloud : config : server : git : uri : https://github.com/KimTaeKang57/capstone-cloud-config.git default-label : master enabled : true 다음과 같이 되어있습니다. 그런데 ec2 서버에서 해서 그런가요. http://localhost:8888/../default에 접근을 하지못하는 오류가 발생하여 탐색과 고민끝에 질문드립니다. - configure-server run : docker run -d -p 8888:8888 —network ecommerce-network -e "spring.profiles.active-default" —name config-service zizoen123/capstone-configure-server:1.0 - user-service run : docker run -d --network ecommerce-network --name user-service -e "eureka.client.serviceUrl.defaultZone=http://discovery-service:8761/eureka/" -e "spring.datasource.url=jdbc:mariadb://mariadb:3306/capstone" zizoen123/capstone-user-service:1.0 run 명령어들은 다음과같습니다.. 뭔가 빠뜨린게 있을까요? 따로 kafka나 zipkin 등등은 모두 사용하지 않고 mariadb만 사용했습니다.
안녕하세요! 실무에서 jpa를 쓰게 되서 강사님의 책과 강의를 번갈아 보면서 열심히 개발하던 중에 궁금한 점이 있어 문의드립니다. 쓰다보니 query dsl이 참 편하더라구요! 그런데 연관관계 없는 두 개 entity를 조인해서 데이터를 조회해오고 싶은데, 아래와 같이 쿼리를 작성하니 실행 중에 QuerySyntaxException이 발생합니다. List < HistoryDto > historyList = queryFactory .select ( Projections. fields ( HistoryDto. class, pmntHistoryEntity. approvalNo , pmntHistoryEntity. approvalDate , pmntHistoryEntity. cancelType , pmntHistoryEntity. trxId , pmntHistoryEntity. trxReqDate , creditCardEntity.cardName , creditCardEntity.cardNumber )) .from ( pmntHistoryEntity) .leftJoin ( creditCardEntity) .on ( pmntHistoryEntity. cardToken .eq ( creditCardEntity.cardToken )) .where ( eqUserId ( dto.getUserId ()) , eqOrderId ( dto.getOrderId ()) ) .fetch () ; exception = QuerySyntaxException: begin 0, end -1, length 19 queryDsl에서 연관 관계 없어도 on 절을 통해 join이 가능한 것으로 알고 있는데 projection과 호환이 안되는 걸까요? 하루종일 구글링을 해도 나오질 않네요.. 혹시 알고 계시다면 답변 부탁드립니다 ㅠ_ㅠ
@GetMapping("/api/v2/orders") public List<OrderDto> ordersV2() { List<Order> orders = orderRepository.findAllByString(new OrderSearch()); List<OrderDto> result = orders.stream() .map( o -> new OrderDto(o) ) .collect(Collectors.toList()); return result; } @Data static class OrderDto { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; private List<OrderItem> orderItems; public OrderDto(Order order) { orderId = order.getId(); name = order.getMember().getName(); orderDate = order.getOrderDate(); orderStatus = order.getStatus(); address = order.getDelivery().getAddress(); order.getOrderItems().stream().forEach(o -> o.getItem().getId()); orderItems = order.getOrderItems(); } } 위 코드에서 OrderDto 생성자 함수 내에 getOrderItem 요소들을 순회시, 각 아이템을 get후에 getId를 호출 할 때 각 item 프록시들이 초기화 돼야 하는 것 아닌가요..? 강의에서는 getName을 통해 초기화 하길래, 위 코드처럼 getId로 하면 될까 궁금증이 생겨 실행해보니 orderItems 내에 item 이 null 값으로 나옵니다. getName 으로 초기화 할 때는 전부 다 들어있구요. 코드 구글 드라이브 링크: https://drive.google.com/drive/folders/17gdIodVzIPG8_XzTeYUVDbLdaScP6c2s
안녕하세요 강의 잘 보고 있습니다. 다름이 아니라 제가 Spring Security로 예제를 만들어보고 있었습니다. 그런데 익명 사용자인 경우 컨트롤러의 Authentication 파라미터로 주입되지 않더라고요. @GetMapping("/authentication") @ResponseBody public String authenticationTest(Authentication authentication) 예를 들면 컨트롤러에 이런 함수를 만들면 일반적인 인증 사용자인 경우에는 Authentication 객체가 주입되지만 익명 사용자인 경우에는 Authentication객체가 주입되지 않았습니다. 이유를 찾아보니 표준 서블릿 API 스펙을 따르기 위해서라고 합니다. 다른 응용 프로그램이 spring security의 구현에 의지하지 않도록 하기 위해서고 굳이 익명 사용자인 경우에도Authentication 객체를 주입받고 싶으면 spring security의 getContext().getAuthentication() api를 사용하면 된다고 합니다. 그래서 이유에 대해서는 제가 이렇게 찾아서 궁금한 부분은 아닌데요. https://github.com/spring-projects/spring-security/issues/4011 이 링크에 가보시면 내부적으로 왜 Authentication 객체가 익명 사용자인 경우 컨트롤러에 주입이 안 되는지 나온 부분이 있습니다. SecurityContextHolderAwareRequestWrapper이 객체에 아래와 같은 부분이 있다는 것입니다. private Authentication getAuthentication() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (!trustResolver.isAnonymous(auth)) { return auth; } return null; } SecurityContextHolderAwareRequestWrapper 객체는 HttpServletRequest가 RequestCacheAwareFilter를 통과하면서 재구성된 request 객체라고 합니다. 그래서 SecurityContextHolderAwareRequestWrapper객체에서 getAuthentication()라는 함수를 호출해서 Controller의 Authentication 타입 파라미터에 주입해주는 Security전용 HandlerMethodArgumentResolver가 있을 것 같은데, 제가 아무리 찾아봐도 정확히 이런 Resolver가 있다는 글을 못 찾겠더라고요. 혹시 아신다면 알려주시면 감사하겠습니다.
jobLauncherTestUtils에 강의에서도 보면 빨간 밑줄표시가 되어 있는데요 Could not autowire. No beans of 'JobLauncherTestUtils' type found 경고 문구를 보면 위에처럼 해당 타입의 빈을 찾을수 없다는 표시인데 실행하면 잘 되더라구요.. 그냥 무시하기에는 찝찝해서 왜 이런건지 혹시 알 수 있을까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] h2데이터베이스 서버모드로 해두었고 서버에 접속도 잘됍니다. java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363) 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:362) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) at java.base/java.util.Optional.orElseGet(Optional.java:364) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) 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:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) 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:71) 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:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.jpa-org.springframework.boot.autoconfigure.orm.jpa.JpaProperties': Could not bind properties to 'JpaProperties' : prefix=spring.jpa, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.jpa.show-sql' to boolean at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:144) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ... 71 more Caused by: org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.jpa-org.springframework.boot.autoconfigure.orm.jpa.JpaProperties': Could not bind properties to 'JpaProperties' : prefix=spring.jpa, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.jpa.show-sql' to boolean at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:92) at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:78) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ... 98 more Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.jpa.show-sql' to boolean at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:384) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:344) at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:469) at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:95) at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:83) at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:59) at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:473) at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:587) at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:573) at org.springframework.boot.context.properties.bind.Binder$Context.access$300(Binder.java:534) at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:471) at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:411) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:340) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:329) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:259) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:246) at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:95) at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:89) ... 112 more Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [boolean] for value 'ture'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value 'ture' at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:109) at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:100) at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:92) at org.springframework.boot.context.properties.bind.Binder.bindProperty(Binder.java:456) at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:400) at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:340) ... 128 more Caused by: java.lang.IllegalArgumentException: Invalid boolean value 'ture' at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:66) at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:32) at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386) at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ... 135 more 위와 같이 에러가 뜨는데 인프런 홈페이지에 같은 오류코드 질문이 있어 확인해봤습니다. JPA와 DB설정, 동작확인 과정 에러 - 인프런 | 질문 & 답변 (inflearn.com) 여기에서 yml설정을 바꿔보라 하셨는데 yml파일이 어디에 있는지 모르겠고 혹시 다른 문제로 오류가 생겼을까요?
안녕하세요 강사님. 완강 후 현재 2회차 수강중에 있습니다. 몇 가지 여쭤볼게 있어서 이렇게 문의드립니다. 제가 공부한 내용을 정리하는 개인 블로그가 있는데 출처를 남기고 강사님의 강의 내용을 토대로 공부한 내용을 정리해서 포스팅해도 괜찮을까요? 혹시 괜찮으시다면 강의때 사용하셨던 ppt 의 이미지 같은 부분들을 인용해서 정리해도 괜찮으실까요? 출처는 반드시 남기겠습니다! 좋은 강의 감사드립니다.