월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 데이터 JPA
JPA의 궁금점
JPA같은 경우에는 관계형 데이터베이스와 객체를 서로 매핑할수있게 하는 프레임워크인걸로 알고있습니다 그러면 이때 MySQL, Oracle 같은 데이터베이스가 있는데 이때 이 데이터베이스는 RDB 기반인데, 그러면 빅데이터를 위해 사용하는 Impala, Hive 같은 DB는 MPP DB도 JPA 프레임워크를 사용이 가능할까요?
- 미해결실전! 스프링 데이터 JPA
h2 db 연결에 문제가 있는 것 같습니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요! 백엔드 개발자가 되고 싶어 김영한님 강의 들으며 공부하는 대학생입니다. 다름이 아니라, 강의를 들으면서 findByUsernameAndAgeGreaterThen 테스트를 진행하다가 발생한 오류를 해결하지 못하고 있습니다ㅠㅠ 요류 내용은 아래에 기재해놓았습니다. 찾아보니까 h2 db를 연결 확인, yml 파일 확인 이라는 답변이 많아서 둘 다 해보았는데 해결이 되지 않습니다. 2번째로 기재한 사진의 버전에 맞게 현재 h2 db 2.1.214 버전을 사용하고 있습니다! 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.BeanCreationException: Error creating bean with name 'memberRepository' defined in study.datajpa.repository.MemberRepository 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 study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int); Reason: Failed to create query for method public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int)! No property 'greaterThen' found for type 'int' Traversed path: Member.age.; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int)! No property 'greaterThen' found for type 'int' Traversed path: Member.age. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) 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.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:936) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:132) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ... 71 moreCaused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int); Reason: Failed to create query for method public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int)! No property 'greaterThen' found for type 'int' Traversed path: Member.age.; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int)! No property 'greaterThen' found for type 'int' Traversed path: Member.age. at org.springframework.data.repository.query.QueryCreationException.create(QueryCreationException.java:101) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:107) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:95) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) at java.base/java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1061) at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845) 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.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:97) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:87) at java.base/java.util.Optional.map(Optional.java:260) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:87) at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:365) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:323) at org.springframework.data.util.Lazy.getNullable(Lazy.java:231) at org.springframework.data.util.Lazy.get(Lazy.java:115) at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:329) at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ... 86 moreCaused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List study.datajpa.repository.MemberRepository.findByUsernameAndAgeGreaterThen(java.lang.String,int)! No property 'greaterThen' found for type 'int' Traversed path: Member.age. at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:96) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:119) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:259) at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:93) at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:103) ... 108 moreCaused by: org.springframework.data.mapping.PropertyReferenceException: No property 'greaterThen' found for type 'int' Traversed path: Member.age. at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:91) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:438) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:414) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:448) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:471) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:471) at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:414) at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:367) at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:349) at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:332) at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81) at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:250) 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.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) 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.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:251) at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:384) 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.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) 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.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:385) at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:96) at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:89) ... 112 more
- 해결됨실전! 스프링 데이터 JPA
메서드명으로 쿼리날릴때 지연로딩에 대해 질문이 있습니다!
1. 네이밍으로 쿼리를 날리게되면 엔티티에서 레이지로딩으로 처리해놓은 속성들을은 언제 가져오게 되는걸까요? 2. update같은경우에 변경감지로 업데이트를 하게되는데 update는 네이밍으로 쿼리를 만들수 없을까요?
- 미해결실전! 스프링 데이터 JPA
GeneratedValue 공유 및 left join 질문
안녕하세요! 유익한 강의 잘 보고 있습니다. Native Query 테스트하는 중에 궁금한 점이 있어서 질문드립니다. @GeneratedValue 는 다른 Entity 끼리 공유하는건가요? Team을 2개 생성하고 Member를 생성하는데 아래 테스트 코드에서 보면 Member의 GeneratedValue 값이 1이 아니라 3부터 시작합니다. NativeQuery에서 left join을 할 때 join 조건을 주고 싶은데 Team entity의 name은 어떻게 접근해야 할까요? @Query(value = "select m.member_id as id, m.name as name, t.name as teamName from member m left join team t ", nativeQuery = true, countQuery = "select count(*) from member") 이 쿼리를 쓰면 full join이 되서 12개의 row가 검색됩니다. on 조건이나 where 절에서 m.teamName = t.name 의 조건을 주고 싶으면 m.teamName 이라는 값을 어떻게 가져와야 하나요 ? createdDate, updatedDate를 BaseEntity로 분리하면 @ToString(of = "createdDate, updatedDate") 에서 사용할 수 없는건가요 ? public class Member extends BaseEntity { @Id@GeneratedValue @Column(name = "member_id") private Long id; private String name; private String sex; private Integer age; private String city; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; public Member(String name, String sex, Integer age, String city, Team team) { this.name = name; this.sex = sex; this.age = age; this.city = city; if(team != null) changeTeam(team); } // 양방향 연관관계 한번에 처리(연관관계 편의 메소드) public void changeTeam(Team team) { this.team = team; team.getMembers().add(this); } } public class Team { @Id @GeneratedValue @Column(name = "team_id") private Long id; @NonNull private String name; @OneToMany(mappedBy = "team") List<Member> members = new ArrayList<>(); } @Test public void nativeQuery() { Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); teamRepository.save(teamA); teamRepository.save(teamB); memberRepository.save(new Member("1", "남자", 18, "서울", teamA)); memberRepository.save(new Member("2", "남자", 19, "경기", teamA)); memberRepository.save(new Member("3", "여자", 20, "부산", teamB)); memberRepository.save(new Member("4", "여자", 21, "울산", teamB)); memberRepository.save(new Member("5", "남자", 22, "포항", teamA)); memberRepository.save(new Member("6", "여자", 23, "전주", teamA)); Member selectedMember = memberRepository.findNativeQueryByName("2"); assertThat(selectedMember.getName()).isEqualTo("2"); Page<MemberProjection> page = memberRepository.findByProjection(PageRequest.of(0, 20)); List<MemberProjection> content = page.getContent(); System.out.println("==============================="); teamRepository.findAll().forEach(System.out::println); System.out.println("==============================="); memberRepository.findAll().forEach(System.out::println); System.out.println("==============================="); for(MemberProjection mp : content){ System.out.println("[ id = " + mp.getId() + ", name = " + mp.getName() + ", teamName = " + mp.getTeamName() + "]"); } }
- 미해결실전! 스프링 데이터 JPA
컬렉션 페치조인 batch size 활용 후 두개이상의 depth의 toOne 관계 lazy loading 시 join 이나 한방쿼리 활용방법 질문
안녕하세요! 개인 프로젝트 중 만난 상황에 대해 질문이 있습니다! 컬렉션 페치조인, 페이징 처리시, batch size 를 활용하여 최적화를 진행 중입니다. 위와 같은 erd 에서 아티클을 페이징 조회 하면서 프로필, 태그 목록 까지 조회하고 싶습니다. 이때 아티클당 작성자의 프로필은 toOne 관계 이기 때문에 fetch join을 활용 하여 진행할 수 있었습니다. 이후에 프록시로 조회된 아티클 태그를 batch Size 를 이용해 n+1 문제 없이 조회하고 아티클 태그 에서는 태그를 조회해서 아티클->아티클태그->태그의 연관을 땡겨 올 수 있습니다. 결국 총 3회의 쿼리가 발생하는데 아티클 태그, 태그를 조회하는 추가 쿼리를 join 이나 where 절을 사용해 한방 쿼리로 묶을 수 있는 방법이 있는지 궁금합니다. @Override public List<ArticleJpaEntity> searchArticle(long offset, long limit) { //쿼리 1 List<ArticleJpaEntity> articles = query .selectFrom(articleJpaEntity) .distinct() .join(articleJpaEntity.authorProfile, profileJpaEntity).fetchJoin() .offset(offset) .limit(limit) .fetch(); //아티클 -> 아티클 태그 -> 태그의 lazy loading : 쿼리 2, 쿼리 3 /* ArticlJpaEntity 의 메서드 public List<String> getTagList() { //쿼리 2: 아티클 -> 아티클 태그 레이지 로딩 발생 return articleTags.stream() //쿼리 3 : 아티클 태그 -> 태그의 레이지 로딩 발생 .map(ArticleTagJpaEntity::getTagName).collect(toList()); } */ //조회된 아티클을 돌며 수동 레이지 로딩 - batch size 로 n+1 방지 for (ArticleJpaEntity article : articles) { article.getTagList(); } return articles; } querydsl 을 활용하였고 활용한 코드는 위와 같습니다. 발생한 쿼리를 요약하면 아래와 같습니다. 쿼리 1 select distinct a.*, p.* from article a inner join profile p on a.author_profile_id = p.id limit 20 쿼리 2 select at.* from article_tag at where at.article_id in (7, 8, 9) 쿼리 3 select t.* from tag t where t.id in (16, 17, 18) 참고로 전체 데이터는 아래와 같습니다. insert into profile (bio, image, user_id, username, id) values ('user1bio', 'user1image', 1, 'user1', 4); insert into profile (bio, image, user_id, username, id) values ('user2bio', 'user2image', 2, 'user2', 5); insert into profile (bio, image, user_id, username, id) values ('user3bio', 'user3image', 3, 'user3', 6); insert into article (author_profile_id, body, created_at, description, slug, title, updated_at, id) values (4, 'article7body', '2022-07-11 22:42:43', 'article7desc', 'article7slug', 'article7title', NULL, 7); insert into article (author_profile_id, body, created_at, description, slug, title, updated_at, id) values (5, 'article8body', '2022-07-11 22:42:43', 'article8desc', 'article8slug', 'article8title', NULL, 8); insert into article (author_profile_id, body, created_at, description, slug, title, updated_at, id) values (6, 'article9body', '2022-07-11 22:42:43', 'article9desc', 'article9slug', 'article9title', NULL, 9); -- 태그 16, 17, 18 insert into tag (name, id) values ('tag16', 16); insert into tag (name, id) values ('tag17', 17); insert into tag (name, id) values ('tag18', 18); -- 아티클 7 -> 아티클 태그 19 -> 태그 16 - tag16 -- 아티클 8 -> 아티클 태그 20 -> 태그 16 - tag16 -- 아티클 8 -> 아티클 태그 21 -> 태그 17 - tag17 -- 아티클 9 -> 아티클 태그 22 -> 태그 16 - tag16 -- 아티클 9 -> 아티클 태그 23 -> 태그 17 - tag17 -- 아티클 9 -> 아티클 태그 24 -> 태그 18 - tag18 insert into article_tag (article_id, tag_id, id) values (7, 16, 19); insert into article_tag (article_id, tag_id, id) values (8, 16, 20); insert into article_tag (article_id, tag_id, id) values (8, 17, 21); insert into article_tag (article_id, tag_id, id) values (9, 16, 22); insert into article_tag (article_id, tag_id, id) values (9, 17, 23); insert into article_tag (article_id, tag_id, id) values (9, 18, 24); === 요약 - 쿼리 2와 쿼리 3을 한방 처리 할 수 있나요??
- 미해결실전! 스프링 데이터 JPA
현업에서 updatedAt 을 설계하나요?! (시스템/비즈니스 입장에서 )
학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 영한님 혹은 서포터즈 여러분 안녕하세요!강의를 열심히 수강하고 있었는데..프로젝트를 수행하던 도중 의문이 들어 하나 질문할게요! ㅎcreatedAt이나 updatedAt을 이용하면 운영상에 발생한 이슈들을 추적할 때 도움이 되는 것으로 알고 있어요!다만 updatedAt은 Entity 객체 혹은, DB의 row 의 일부분이 변경되면 바뀌는 것으로 알고 있거든요!이부분에서 질문 드립니다 ! 게시글 조회수가 올라가는 로직이 있다는 가정하에 이로 인하여 게시글 수정일시가 변경되면 안된다고 할 때 JPA/스프링에서 제공하는 변경감지 updatedAt을 사용할 수가 없거든요!이때는 별도로 시스템차원에서 변경한 systemUpdatedAt 과 비즈니스 의미상으로 변경한 businessUpdatedAt 등으로 나누는 것이 좋을까요??기타)createdAt은 시스템 입장에서 변경 / 비즈니스 입장에서 변경한 내역이 똑같은 것 같아용!
- 미해결실전! 스프링 데이터 JPA
안녕하세요 영한님! 네이티브 쿼리 사용이 적절한 상황인지 궁금해서 질문드려요
우선 제가 하려는 동작은 "특정 브랜드의 카테고리별 상품의 최저가의 합" 을 구하는 쿼리를 작성해야했었고 결과물 쿼리는 " select sum(temp_mins.mins) as total from ( select min(price) mins from product where brand_num = ? group by category_num) as temp_mins" 위처럼 작성했습니다. 코드는 @Query(value = "select sum(temp_mins.mins) as total from (select min(price) mins from product where brand_num = ? group by category_num) as temp_mins", nativeQuery = true)Integer sumLowestPriceEachCategoryByBrand(Long brandNum); 입니다. queryDsl이나 JPQL에선 from절의 서브쿼리 기능을 제공하지 않는다고 파악되어서 고민끝에 네이티브 쿼리까지 왔는데요.현재 강의에서 네이티브 쿼리의 대표적인 단점으로 뽑아주신게 반환타입 부분으로 학습했는데 제 생각으로는 단순한 박싱 타입으로 반환하기 때문에 크게 문제가 없다고 생각됩니다. 혹시 위 코드가 네이티브 쿼리를 사용하는데 적절한 상황일까요?
- 미해결실전! 스프링 데이터 JPA
join 된 entity save시 cast 문제질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 우선 좋은강의 감사합니다. jpa수업을 들으며 개인적으로 응용해보며 공부하고 있습니다. 해당 질문은 개인적으로 응용하며 공부하던 중 발생한 문제에 대한 문의입니다. User Entity 1 : N Scrap Entity 구조에서 Scrap.java 의 addUser method를 구현하여 동시에 저장하려고 했습니다. 헌데 user Entity를 cast하지 못했다고 에러가 발생한것으로 보입니다. java.lang.ClassCastException: Cannot cast com.api.jpaTest.domain.entity.User to java.lang.String 해당 내용에 대한 힌트라도 알고싶습니다. token에서 user에 대한 정보는 정확히 가져왔고 해당 정보를 바탕으로 DB에서 User Entity를 정상적으로 조회하였습니다. scrap은 json 더미데이터가 있어서 데이터 역시 정상적으로 파싱하였습니다. 아래 코드 중 ScrapService.java 의 scrap() method 중 sr.save(userScrap)에서 오류가 발생합니다. User.java ( user Entity ) @Schema(description = "API 사용자 정보") @Builder @Table(name = "user") @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @ToString public class User extends BaseTimeEntity implements UserDetails { @Schema(description = "user table pk",defaultValue = "db generateValue") @Id @GeneratedValue @JsonIgnore @Column(name = "user_no") private Long id; @Schema(description = "user id") @Column(name = "user_id") private String userId; @Schema(description = "사용자 이름") @Column(name = "name") private String name; @Schema(description = "비밀번호") @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @Column(name = "password") private String password; @Schema(description = "주민번호") @Column(name = "reg_no") private String regNo; @ElementCollection(fetch = FetchType.EAGER) @Builder.Default private List<String> roles = new ArrayList<>(); @Schema(description = "스크랩 정보 리스트") @JsonIgnore @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) @ToString.Exclude private List<Scrap> scraps = new ArrayList<>(); public void encodePassword(String password) { this.password = password; } public void encodeRegNo() throws EncodingException { this.regNo = AES256Util.encrypt(this.regNo); } public String decodeRegNo() throws EncodingException { return AES256Util.decrypt(this.regNo); } // security // @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } @Override public String getUsername() { return this.userId; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } Scrap.java ( scrap Entity ) @Schema(description = "사용자 scrap 정보") @Builder @Table(name = "scrap") @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @ToString public class Scrap extends BaseEntity { @Schema(description = "scrap table pk") @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @Id @GeneratedValue @Column(name = "scrap_no") private Long id; @Schema(description = "스크랩 성공 여부") @Column(name = "status") private String status; @Schema(description = "스크랩 에러 메세지") @Column(name = "errors") private String errors; @Schema(description = "스크랩 데이터 정보") @Embedded private ScrapPayData scrapPayData; @Schema(description = "스크랩 요청 일자") @Column(name = "worker_res_dt") private String workerResDt; @Schema(description = "스크랩 응답 일자") @Column(name = "worker_req_dt") private String workerReqDt; @Schema(description = "app version") @Column(name = "app_ver") private String appVer; @Schema(description = "user 정보") @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "user_no") // @ToString.Exclude private User user; public void setUser(User user) { this.user = user; } public void addUser(User user) { this.user = user; user.getScraps().add(this); } } ScrapService.java @Transactional public Result scrap() throws OtherException, EncodingException { User user = userService.getUser(); <-------- User Entity 정보 있음 ( 정상 조회 ) Scrap userScrap = getUserScrap(user); <----------- 더미 데이터를 기반으로 데이터 생성하여 데이터 있음 userScrap.addUser(user); sr.save(userScrap); <-----------저장 시 java.lang.ClassCastException: Cannot cast "User Entity path" to java.lang.String 에러 발생 return Result.builder() .statues(ApiStatus.SUCCESS) .data(userScrap.getId()) .errors("") .build(); } @Transactional Scrap getUserScrap(User user) throws EncodingException, OtherException { HashMap<String, String> jsonMap = new HashMap<>(); jsonMap.put("name",user.getName()); jsonMap.put("regNo",user.decodeRegNo()); JSONObject requestJson = new JSONObject(jsonMap); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<String>(requestJson.toString(),headers); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(20000); requestFactory.setReadTimeout(20000); RestTemplate restTemplate = new RestTemplate(requestFactory); ResponseEntity<String> response = restTemplate.postForEntity( ScrapConstant.URL.getMsg(), entity, String.class ); return jsonToEntity(response.getBody()); } Scrap jsonToEntity(String json) throws OtherException { try { ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); ScrapDto scrapDto = mapper.readValue(json, ScrapDto.class); JSONObject data = new JSONObject(mapper.writeValueAsString(scrapDto.getData())); JSONObject jsonList = new JSONObject(mapper.writeValueAsString(scrapDto.getData())).getJSONObject(ScrapConstant.LIST.getMsg()); JSONArray scrap002 = jsonList.getJSONArray(ScrapConstant.SCRAP_NUM2.getMsg()); JSONArray scrap001 = jsonList.getJSONArray(ScrapConstant.SCRAP_NUM1.getMsg()); return Scrap.builder() .status(scrapDto.getStatus()) .errors(scrapDto.getErrors().toString()) .appVer((String) data.get("appVer")) .workerReqDt((String) data.get("workerReqDt")) .workerResDt((String) data.get("workerResDt")) .scrapPayData( new ScrapPayData((String) scrap002.getJSONObject(0).get("총사용금액"), (String) scrap001.getJSONObject(0).get("총지급액")) ) .build(); } catch (Exception e) { throw new OtherException(e); } } Exception Message java.lang.ClassCastException: Cannot cast com.api.jpaTest.domain.entity.User to java.lang.String at java.base/java.lang.Class.cast(Class.java:3605) ~[na:na] at com.api.jpaTest.domain.entity.Scrap_Accessor_kqrtpb.setProperty(Unknown Source) ~[classes/:na] at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:104) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:127) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:171) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.lambda$setProperty$0(MappingAuditableBeanWrapperFactory.java:259) ~[spring-data-commons-2.6.2.jar:2.6.2] at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setProperty(MappingAuditableBeanWrapperFactory.java:259) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setCreatedBy(MappingAuditableBeanWrapperFactory.java:204) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.touchAuditor(AuditingHandlerSupport.java:169) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.lambda$touch$0(AuditingHandlerSupport.java:136) ~[spring-data-commons-2.6.2.jar:2.6.2] at java.base/java.util.Optional.map(Optional.java:265) ~[na:na] at org.springframework.data.auditing.AuditingHandlerSupport.touch(AuditingHandlerSupport.java:134) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandlerSupport.markCreated(AuditingHandlerSupport.java:114) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.auditing.AuditingHandler.markCreated(AuditingHandler.java:92) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.jpa.domain.support.AuditingEntityListener.touchForCreate(AuditingEntityListener.java:92) ~[spring-data-jpa-2.6.2.jar:2.6.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.hibernate.jpa.event.internal.ListenerCallback.performCallback(ListenerCallback.java:55) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:97) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preCreate(CallbackRegistryImpl.java:57) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:760) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:746) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy142.persist(Unknown Source) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy142.persist(Unknown Source) ~[na:na] at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:637) ~[spring-data-jpa-2.6.2.jar:2.6.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.6.2.jar:2.6.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy159.save(Unknown Source) ~[na:na] at com.api.jpaTest.service.ScrapService.scrap(ScrapService.java:50) ~[classes/:na] at com.api.jpaTest.service.ScrapService$$FastClassBySpringCGLIB$$46dc0c0.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.16.jar:5.3.16] at com.api.jpaTest.service.ScrapService$$EnhancerBySpringCGLIB$$b9877c5.scrap(<generated>) ~[classes/:na] at com.api.jpaTest.controller.ScrapController.scrap(ScrapController.java:33) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at com.api.jpaTest.config.jwt.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:33) ~[classes/:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
- 미해결실전! 스프링 데이터 JPA
실무에서 DTO 타입으로 바로 반환하는 사례가 궁금합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요. 강의 항상 잘 듣고 있습니다 ^^ DB의 검색 결과를 바로 DTO 타입으로 반환 받는 사례가 실무에서 어떤 경우에 발생하는 지 궁금합니다! 도메인 모델에서 DTO로 타입 변환은 프레젠테이션 계층에서 수행하는 게 관리 포인트를 한 곳에 모을 수 있어 효율적이라고 알고 있습니다. 혹은 요구사항이 변해서 다른 DTO 로 반환해야 하는 경우에, DB에서 바로 DTO 타입으로 조회하게 되면 여러 영역을 다 수정해야 하기 때문에 Controller 까지는 Entity로 운반하고, Controller 에서 DTO로 변환하는 게 나아 보이는데요 ! 실무에서 어떤 경우에 바로 DTO 타입으로 리턴 받도록 하는지 궁금합니다 ! 아니면 혹시 제가 생각하고 있는 부분에서 잘못 생각한 게 있을까요 ^^
- 미해결실전! 스프링 데이터 JPA
save 할 때 트랜잭션 관련 질문
save같이 persist가 날라가는 기능들은 트랜잭션 안에서 동작해야 작동하고 @PostConstruct에서는 @Transection이 적용이 안돼서 별도의 클래스를 만들어서 @PostConstruct를 활용하는 걸로 알고있었는데 강의 보니까 @PostConstruct에서 @Transactional없이 그냥 save해도 insert가 되던데 이유가 궁금합니다!
- 미해결실전! 스프링 데이터 JPA
assertThat관해서 질문있습니다
assertThat(A).isEqualTo(B); assertEquals(A,B); 두가지 같은것이 맞나요?
- 미해결실전! 스프링 데이터 JPA
개발하고 있는 프로젝트에 Querydsl을 적용해보려고 테스트 중입니다.
1. build.gradle에 설정 후 Q파일 생성까지 완료 2. 환경 설정 검증용 엔티티 생성 후 테스트 프로그램 완료 3. 테스트 실행 후 에러 발생 E:\workspace\ECS-server\ecs\build\generated\querydsl\com\weni\ecs\domain\QEduAcnt.java:16: error: cannot find symbol public class QEduAcnt extends EntityPathBase<EduAcnt> { ^ symbol: class EduAcnt 4. 에러를 찾을 수 없어서 해당 파알을 삭제 후 테스트 프로그램 실행 @Testvoid contextLoads() { JPAQueryFactory query = new JPAQueryFactory(em); QHello qHello = QHello.hello; //Querydsl Q타입 동작 확인 List<Hello> result = query .selectFrom(qHello).fetch(); System.out.println("result = " + result);} 5. 테스트 성공 Hibernate: select hello0_.id as id1_7_ from Hello hello0_ 2022-06-30 21:58:16.019 INFO 30456 --- [ Test worker] jdbc.sqltiming : select hello0_.id as id1_7_ from Hello hello0_ {executed in 2 msec} 2022-06-30 21:58:16.036 INFO 30456 --- [ Test worker] jdbc.resultsettable : |-------| |id1_7_ | |-------| |1 | |2 | |3 | |-------| result = [com.weni.ecs.domain.Hello@133fb509, com.weni.ecs.domain.Hello@bb0ca30, com.weni.ecs.domain.Hello@6e6d544] Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. See https://docs.gradle.org/7.2/userguide/command_line_interface.html#sec:command_line_warnings BUILD SUCCESSFUL in 15s 6 actionable tasks: 4 executed, 2 up-to-date 오후 9:58:16: Execution finished ':test --tests "com.weni.ecs.domain.QuerydslApplicationTests.contextLoads"'. 6. 다시 테스트를 실행하면 다시 생성된 Q파일떄문에 또 에러 발생합니다. import java.math.BigDecimal; import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.PostLoad; import javax.persistence.PrePersist; import javax.persistence.PostPersist; import javax.persistence.PreUpdate; import javax.persistence.PostUpdate; import javax.persistence.PreRemove; import javax.persistence.PostRemove; // import org.springframework.beans.BeanUtils; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Builder; @Entity @Table(name="EDU_ACNT") //--PRIMARY @Getter @NoArgsConstructor // (access = AccessLevel.PROTECTED) // AccessLevel.PUBLIC @EqualsAndHashCode // (of = {"email","name"}, callSuper = true, onParam = @__(@NonNull)) @ToString //(exclude = "password") // exclude 속성을 사용하면, 특정 필드를 toString() 결과에서 제외 public class EduAcnt { @Id // Integer @Column(name = "ACNT_NO", nullable = false) private Integer acntNo; //--null @Column(name = "BALANCE", precision = 18, scale = 0, nullable = false) private BigDecimal balance; //--null @Builder public EduAcnt(Integer acntNo, BigDecimal balance) { this.acntNo = acntNo; this.balance = balance; } //---------------------------------------------------- // Load/Persist/Update/Remove(조회/신규/수정/삭제) // Entity Pre/Post(이전/이후) 처리에 대한 정의(PreLoad는 없음) // * DB의 Trigger와 비슷한 JPA기능 //---------------------------------------------------- @PostLoad public void onPostLoad() { } @PrePersist public void onPrePersist() { } @PostPersist public void onPostPersist() { } @PreUpdate public void onPreUpdate() { } @PostUpdate public void onPostUpdate() { } @PreRemove public void onPreRemove() { } @PostRemove public void onPostRemove() { } }
- 미해결실전! 스프링 데이터 JPA
@PersistenceContext
안녕하세요. 강사님.. @PersistenceContext 역할에 대해 문의드립니다. JPA 활용 강의에서는 private final EntityManager em; 로 선언하여 생성자로 주입 받았는데, 이번 강의에서는 @PersistenceContext 를 사용하고 있습니다. 용법의 차이가 있는 건가요?? 감사합니다.
- 미해결실전! 스프링 데이터 JPA
바뀐 column을 알 수 있나요?
영한님 안녕하세요. 강의 잘 듣고 있습니다. auditing 관련해서 질문이 있습니다. created_data, update_date, create_by, update_by를 테이블 컬럼에 추가해서 데이터의 변화 이력을 넣는 게 좋다는 건 이해했는데, 이 4개의 정보로 알 수 있는 건 변경 일시와 변경한 주체 정도인데, 한 테이블에 컬럼이 수 십 개 정도라고 하면 어떤 컬럼이 변경됐는지 모른다면 크게 의미가 없는 거 아닌가라는 생각이 들어서요.. 어떤 column이 변경됐다는 정보는 알 방법이 없을까요?(이런 건 히스토리 테이블 등으로 해결해야 할까요?)
- 미해결실전! 스프링 데이터 JPA
페이징 slice관련
slice나 page 일단 page는그래도 예제로보여주셨는데slice는 구글링해도 예제도없고 그런데 어디서볼수있는게있을까요 콘솔이나 테스트코드에서말고 뷰단까지의 더보기버튼같은 까지의 어떻게 구현이되는지 알고싶습니다
- 미해결실전! 스프링 데이터 JPA
MemberJpaRepositoryTest / insert 미생성
안녕하세요 MemberJpaRepositoryTest 중 insert 생성이 안되어 h2 테이블이 생성되지 않아 질문 남깁니다. yml 파일도 확인 해보았으나 다른 쪽에 문제가 있는 것 같은데 insert 되지 않는 이유가 assertThat과 연관이 있을까요? 현재 h2 버전은 2.1.212 를 사용하고 있습니다. test junit5로 생성하였습니다. package study.datajpa.repository;import org.junit.jupiter.api.Assertions;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.annotation.Rollback;import org.springframework.transaction.annotation.Transactional;import study.datajpa.entity.Member;import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;import static org.junit.jupiter.api.Assertions.*;@SpringBootTest@Transactional@Rollback(false)class MemberJpaRepositoryTest { @Autowired MemberJpaRepository memberJpaRepository; @Test public void testMember() { Member member = new Member("memberA"); Member savedMember = memberJpaRepository.save(member); Member findMember = memberJpaRepository.find(savedMember.getId()); assertThat(findMember.getId()).isEqualTo(member.getId()); assertThat(findMember.getUsername()).isEqualTo(member.getUsername()); assertThat(findMember).isEqualTo(member); }} spring: datasource: url: jdbc:h2:tcp://localhost/~/datajpa username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create properties: hibernate: #show_sql: true format_sql: truelogging.level: org.hibernate.SQL: debug #org.hibernate.type: trace package study.datajpa.repository;import org.springframework.stereotype.Repository;import study.datajpa.entity.Member;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;@Repositorypublic class MemberJpaRepository { @PersistenceContext private EntityManager em; public Member save(Member member) { em.persist(member); return member; } public Member find(Long id) { return em.find(Member.class, id); }} package study.datajpa.entity;import lombok.Getter;import lombok.Setter;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entity@Getter @Setterpublic class Member { @Id @GeneratedValue private Long id; private String username; protected Member() { } public Member(String username) { this.username = username; }} /Library/Java/JavaVirtualMachines/jdk-11.0.13.jdk/Contents/Home/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=49771:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/kimmin/.m2/repository/org/junit/platform/junit-platform-launcher/1.8.2/junit-platform-launcher-1.8.2.jar:/Users/kimmin/.m2/repository/org/junit/platform/junit-platform-engine/1.8.2/junit-platform-engine-1.8.2.jar:/Users/kimmin/.m2/repository/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar:/Users/kimmin/.m2/repository/org/junit/platform/junit-platform-commons/1.8.2/junit-platform-commons-1.8.2.jar:/Users/kimmin/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA CE.app/Contents/plugins/junit/lib/junit5-rt.jar:/Applications/IntelliJ IDEA CE.app/Contents/plugins/junit/lib/junit-rt.jar:/Users/kimmin/Desktop/study/data-jpa/out/test/classes:/Users/kimmin/Desktop/study/data-jpa/out/production/classes:/Users/kimmin/Desktop/study/data-jpa/out/production/resources:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-data-jpa/2.7.0/773d8c4fbe92493655f4c7db3a2d95388b8f6eb8/spring-boot-starter-data-jpa-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/2.7.0/7bf2381d030023970b5375c1090545e480467aa1/spring-boot-starter-web-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-test/2.7.0/417764bfd907f7deffd617fb31b3ea0900547287/spring-boot-starter-test-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-aop/2.7.0/49f204ec9672800932f8f7b344221251b1422da6/spring-boot-starter-aop-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-jdbc/2.7.0/dd69f21efd63a2a16d631210b5656dc30348451b/spring-boot-starter-jdbc-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/jakarta.transaction/jakarta.transaction-api/1.3.3/c4179d48720a1e87202115fbed6089bdc4195405/jakarta.transaction-api-1.3.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/jakarta.persistence/jakarta.persistence-api/2.2.3/8f6ea5daedc614f07a3654a455660145286f024e/jakarta.persistence-api-2.2.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.hibernate/hibernate-core/5.6.9.Final/8ec2c7b13de2fbcb19feddfb3a30932bb6a8228a/hibernate-core-5.6.9.Final.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.data/spring-data-jpa/2.7.0/f82986cdf2beda49b0bbb28a880ca644a1eb6c42/spring-data-jpa-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aspects/5.3.20/161a2ccb1d68aed17922981909081bd6d1e46628/spring-aspects-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-json/2.7.0/f7120f4a6fd5dd2ca2128061e420e45ae2294943/spring-boot-starter-json-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/2.7.0/64fd3c21486dd20df9a62566599337dae2eb62cc/spring-boot-starter-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-tomcat/2.7.0/b8e5cd8cd4bf3935a68468fe32fe2e7550f96b8a/spring-boot-starter-tomcat-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-webmvc/5.3.20/8ac1b72a1f5c41fdc2cb3340cd94f795af260301/spring-webmvc-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/5.3.20/3c2fe9363760d62d5b7c9f087bb4255e3377a0b2/spring-web-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test-autoconfigure/2.7.0/e0270c5cf20211c43f7b485c64e3e6a96f16b991/spring-boot-test-autoconfigure-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test/2.7.0/8be4bc652e4bd0ae0f61b99e164ae26ac269f154/spring-boot-test-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.jayway.jsonpath/json-path/2.7.0/f9d7d9659f2694e61142046ff8a216c047f263e8/json-path-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/jakarta.xml.bind/jakarta.xml.bind-api/2.3.3/48e3b9cfc10752fba3521d6511f4165bea951801/jakarta.xml.bind-api-2.3.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.assertj/assertj-core/3.22.0/c300c0c6a24559f35fa0bd3a5472dc1edcd0111e/assertj-core-3.22.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest/2.2/1820c0968dba3a11a1b30669bb1f01978a91dedc/hamcrest-2.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.8.2/5a817b1e63f1217e5c586090c45e681281f097ad/junit-jupiter-5.8.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-junit-jupiter/4.5.1/f81fb60bd69b3a6e5537ae23b883326f01632a61/mockito-junit-jupiter-4.5.1.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-core/4.5.1/ed456e623e5afc6f4cee3ae58144e5c45f3b3bf/mockito-core-4.5.1.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.skyscreamer/jsonassert/1.5.0/6c9d5fe2f59da598d9aefc1cfc6528ff3cf32df3/jsonassert-1.5.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-test/5.3.20/33a92d5066fb810023969a0d70fac96387962769/spring-test-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.3.20/4b88aa3c401ede3d6c8ac78ea0c646cf326ec24b/spring-core-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.xmlunit/xmlunit-core/2.9.0/8959725d90eecfee28acd7110e2bb8460285d876/xmlunit-core-2.9.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/5.3.20/c82f17997ab18ecafa8d08ce34a7c7aa4a04ef9e/spring-aop-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.aspectj/aspectjweaver/1.9.7/158f5c255cd3e4408e795b79f7c3fbae9b53b7ca/aspectjweaver-1.9.7.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jdbc/5.3.20/140414df1080754fcefe12921543c599e51dfbb2/spring-jdbc-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.zaxxer/HikariCP/4.0.3/107cbdf0db6780a065f895ae9d8fbf3bb0e1c21f/HikariCP-4.0.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.glassfish.jaxb/jaxb-runtime/2.3.6/1e6cd0e5d9f9919c8c8824fb4d310b09a978a60e/jaxb-runtime-2.3.6.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.hibernate.common/hibernate-commons-annotations/5.1.2.Final/e59ffdbc6ad09eeb33507b39ffcf287679a498c8/hibernate-commons-annotations-5.1.2.Final.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.jboss.logging/jboss-logging/3.4.3.Final/c4bd7e12a745c0e7f6cf98c45cdcdf482fd827ea/jboss-logging-3.4.3.Final.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.12.10/f34127d93639fad8c6fb84b3ca30292697d6c55d/byte-buddy-1.12.10.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/antlr/antlr/2.7.7/83cd2cd674a217ade95a4bb83a8a14f351f48bd0/antlr-2.7.7.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.jboss/jandex/2.4.2.Final/1e1c385990b258ff1a24c801e84aebbacf70eb39/jandex-2.4.2.Final.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml/classmate/1.5.1/3fe0bed568c62df5e89f4f174c101eab25345b6c/classmate-1.5.1.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/5.3.20/517a42165221ea944c8b794154c10b69c0128281/spring-context-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-orm/5.3.20/4eaf36c114a3aa2d1603834cfb197b5742ccde5b/spring-orm-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.data/spring-data-commons/2.7.0/6dc643cf1512fdc5c2d63f55c83080b60b629d10/spring-data-commons-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-tx/5.3.20/9a4ec2249dc3523ac70e0710a64288c14fc3ff78/spring-tx-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/5.3.20/ab88bd9e3a8307f5c0516c15d295c88ec318659/spring-beans-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.36/6c62681a2f655b49963a5983b8b0950a6120ae14/slf4j-api-1.7.36.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.13.3/ad2f4c61aeb9e2a8bb5e4a3ed782cfddec52d972/jackson-datatype-jsr310-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.module/jackson-module-parameter-names/2.13.3/f71c4ecc1a403787c963f68bc619b78ce1d2687b/jackson-module-parameter-names-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.13.3/d4884595d5aab5babdb00ddbd693b8fd36b5ec3c/jackson-datatype-jdk8-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.13.3/56deb9ea2c93a7a556b3afbedd616d342963464e/jackson-databind-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/2.7.0/483f9a66d0e8326583c5054038d0aa0a95045dc3/spring-boot-autoconfigure-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/2.7.0/df8bd106d6c6a6494b787b71d23cef6d2dc73703/spring-boot-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-logging/2.7.0/5ff2a55d345ad824f39d55eaa32203865a92b30f/spring-boot-starter-logging-2.7.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/1.3.5/59eb84ee0d616332ff44aba065f3888cf002cd2d/jakarta.annotation-api-1.3.5.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/1.30/8fde7fe2586328ac3c68db92045e1c8759125000/snakeyaml-1.30.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-websocket/9.0.63/c0bedf7bad4c0552e1805b2bc802604171c64146/tomcat-embed-websocket-9.0.63.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/9.0.63/f427a282d02439570f1e2af2c00376d4188c5291/tomcat-embed-core-9.0.63.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-el/9.0.63/b595f0bdae0392c8b3c8592fea10023956a3f619/tomcat-embed-el-9.0.63.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/5.3.20/20e179f0dfabf0a46428f22c2150c9c4850fd15d/spring-expression-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/net.minidev/json-smart/2.4.8/7c62f5f72ab05eb54d40e2abf0360a2fe9ea477f/json-smart-2.4.8.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/jakarta.activation/jakarta.activation-api/1.2.2/99f53adba383cb1bf7c3862844488574b559621f/jakarta.activation-api-1.2.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.8.2/ddeafe92fc263f895bfb73ffeca7fd56e23c2cce/junit-jupiter-params-5.8.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.8.2/4c21029217adf07e4c0d0c5e192b6bf610c94bdc/junit-jupiter-api-5.8.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.12.10/1f097f8d6cad60e8f93e5eb670cf5dc9b64da32/byte-buddy-agent-1.12.10.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.vaadin.external.google/android-json/0.0.20131108.vaadin1/fa26d351fe62a6a17f5cda1287c1c6110dec413f/android-json-0.0.20131108.vaadin1.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/5.3.20/35119231d09863699567ce579c21512ddcbc5407/spring-jcl-5.3.20.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.glassfish.jaxb/txw2/2.3.6/45db7b69a8f1ec2c21eb7d4fc0ee729f53c1addc/txw2-2.3.6.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.sun.istack/istack-commons-runtime/3.0.12/cbbe1a62b0cc6c85972e99d52aaee350153dc530/istack-commons-runtime-3.0.12.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.13.3/7198b3aac15285a49e218e08441c5f70af00fc51/jackson-annotations-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.13.3/a27014716e4421684416e5fa83d896ddb87002da/jackson-core-2.13.3.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.11/4741689214e9d1e8408b206506cbe76d1c6a7d60/logback-classic-1.2.11.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-to-slf4j/2.17.2/17dd0fae2747d9a28c67bc9534108823d2376b46/log4j-to-slf4j-2.17.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.slf4j/jul-to-slf4j/1.7.36/ed46d81cef9c412a88caef405b58f93a678ff2ca/jul-to-slf4j-1.7.36.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/net.minidev/accessors-smart/2.4.8/6e1bee5a530caba91893604d6ab41d0edcecca9a/accessors-smart-2.4.8.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/a231e0d844d2721b0fa1b238006d15c6ded6842a/apiguardian-api-1.1.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.8.2/32c8b8617c1342376fd5af2053da6410d8866861/junit-platform-commons-1.8.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.2.0/28c11eb91f9b6d8e200631d46e20a7f407f2a046/opentest4j-1.2.0.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.2.11/a01230df5ca5c34540cdaa3ad5efb012f1f1f792/logback-core-1.2.11.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.17.2/f42d6afa111b4dec5d2aea0fe2197240749a4ea6/log4j-api-2.17.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/9.1/a99500cf6eea30535eeac6be73899d048f8d12a8/asm-9.1.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.h2database/h2/2.1.212/f3187885395bd0c0e0e83f96641bb630f368ee2f/h2-2.1.212.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.8.2/c598b4328d2f397194d11df3b1648d68d7d990e3/junit-jupiter-engine-5.8.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/3.2/7fadf57620c8b8abdf7519533e5527367cb51f09/objenesis-3.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/com.sun.activation/jakarta.activation/1.2.2/74548703f9851017ce2f556066659438019e7eb5/jakarta.activation-1.2.2.jar:/Users/kimmin/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.8.2/b737de09f19864bd136805c84df7999a142fec29/junit-platform-engine-1.8.2.jar com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 study.datajpa.DataJpaApplicationTests,contextLoads 21:53:50.984 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate] 21:53:51.028 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)] 21:53:51.140 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [study.datajpa.DataJpaApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper] 21:53:51.175 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [study.datajpa.DataJpaApplicationTests], using SpringBootContextLoader 21:53:51.188 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [study.datajpa.DataJpaApplicationTests]: class path resource [study/datajpa/DataJpaApplicationTests-context.xml] does not exist 21:53:51.188 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [study.datajpa.DataJpaApplicationTests]: class path resource [study/datajpa/DataJpaApplicationTestsContext.groovy] does not exist 21:53:51.190 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [study.datajpa.DataJpaApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}. 21:53:51.192 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [study.datajpa.DataJpaApplicationTests]: DataJpaApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration. 21:53:51.349 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [study.datajpa.DataJpaApplicationTests] 21:53:51.611 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [/Users/kimmin/Desktop/study/data-jpa/out/production/classes/study/datajpa/DataJpaApplication.class] 21:53:51.614 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration study.datajpa.DataJpaApplication for test class study.datajpa.DataJpaApplicationTests 21:53:51.966 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [study.datajpa.DataJpaApplicationTests]: using defaults. 21:53:51.967 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener] 21:53:52.029 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4983159f, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@44e3a2b2, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@101639ae, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@4c550889, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@1d2bd371, org.springframework.test.context.support.DirtiesContextTestExecutionListener@44040454, org.springframework.test.context.transaction.TransactionalTestExecutionListener@65fe9e33, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@18bc345, org.springframework.test.context.event.EventPublishingTestExecutionListener@42f8285e, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@26bab2f1, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@3724af13, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@68ead359, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@6b53bcc2, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@180da663, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@a43ce46] 21:53:52.039 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@2d36e77e testClass = DataJpaApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@61c9c3fd testClass = DataJpaApplicationTests, locations = '{}', classes = '{class study.datajpa.DataJpaApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@2235eaab, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@45efd90f, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@4a07d605, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68746f22, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@222a59e6, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@2f490758], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true]], class annotated with @DirtiesContext [false] with mode [null]. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.0) 2022-06-14 21:53:53.119 INFO 1570 --- [ main] study.datajpa.DataJpaApplicationTests : Starting DataJpaApplicationTests using Java 11.0.13 on gimminjeong-ui-MacBook-Air.local with PID 1570 (started by kimmin in /Users/kimmin/Desktop/study/data-jpa) 2022-06-14 21:53:53.122 INFO 1570 --- [ main] study.datajpa.DataJpaApplicationTests : No active profile set, falling back to 1 default profile: "default" 2022-06-14 21:53:54.714 INFO 1570 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2022-06-14 21:53:54.745 INFO 1570 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11 ms. Found 0 JPA repository interfaces. 2022-06-14 21:53:55.829 INFO 1570 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2022-06-14 21:53:56.006 INFO 1570 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.9.Final 2022-06-14 21:53:56.653 INFO 1570 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2022-06-14 21:53:56.958 INFO 1570 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2022-06-14 21:53:57.121 INFO 1570 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2022-06-14 21:53:57.239 INFO 1570 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 2022-06-14 21:53:58.795 DEBUG 1570 --- [ main] org.hibernate.SQL : drop table if exists member CASCADE 2022-06-14 21:53:58.805 DEBUG 1570 --- [ main] org.hibernate.SQL : drop sequence if exists hibernate_sequence 2022-06-14 21:53:58.810 DEBUG 1570 --- [ main] org.hibernate.SQL : create sequence hibernate_sequence start with 1 increment by 1 2022-06-14 21:53:58.812 DEBUG 1570 --- [ main] org.hibernate.SQL : create table member ( id bigint not null, username varchar(255), primary key (id) ) 2022-06-14 21:53:58.816 INFO 1570 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2022-06-14 21:53:58.833 INFO 1570 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2022-06-14 21:53:59.270 WARN 1570 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2022-06-14 21:54:00.233 INFO 1570 --- [ main] study.datajpa.DataJpaApplicationTests : Started DataJpaApplicationTests in 8.066 seconds (JVM running for 11.512) 2022-06-14 21:54:00.539 INFO 1570 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2022-06-14 21:54:00.541 INFO 1570 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2022-06-14 21:54:00.560 INFO 1570 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code 0
- 미해결실전! 스프링 데이터 JPA
페이징관련질문
PageRequest pagerequest = PageRequest.of(0, 3)이 있다고하면 첫번째 페이지에 3개의 데이터를 가져오라고하는 말이라고배웠는데 1. 저 of라는게 여기서만 나오는게아니고 여러군데에서 나오는데 정확히 어떨때 쓰는지 알수있을까요 2. 그리고 페이징 처리는 마이바티스 쓸떄는 네비시작페이지 끝페이지 페이지 블록 크기등등 여러가지가 필요한데 그런 정보들이 하나도없는데 저걸로 어떻게 만드는지 예시가없어서 이런건 제가 찾아봐서 하는건가요 페이징강의가 직접구현을 안하고 테스트코드로 콘솔로 찍으니 이해가 잘가지가않습니다.
- 미해결실전! 스프링 데이터 JPA
영속성 컨텍스트에 대해 질문이 있습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. 제가 아직 실무로 JPA를 사용해본적은 없어서 공부만하고 있는데요. 생각해보니까 실무에선 서버가 여러대일 수 있어서 영속성 컨텍스트간의 동기화가 이슈가 될 수 있을것 같은데 이런 부분은 어떻게 해결하나요?동기화나 동시성 등 검색해봤는데 잘 모르겠어서요ㅜ
- 미해결실전! 스프링 데이터 JPA
entitymanager질문
테스트진행중 @PersistenceContext EntityManager em; 이렇게했는데 테스트에서는 @require아규먼트 해서 private final 로쓰면안되는건가요?
- 미해결실전! 스프링 데이터 JPA
엔티티, DTO 유효성 검사에 대해 질문 드립니다.
엔티티, DTO를 둘 다 유효성 검사를 하나요? 만약 엔티티도 유효성 검사를 할 떄 Bean validation을 사용하시나요?