묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemberServiceIntegrationTest 실행 오류 (join함수)
스프링 DB접근기술 섹션에 JPA 파트를 듣고 있는데 MemberServiceIntegrationTest.java 파일에서 join함수를 실행했는데 아래와 같은 오류가 발생하여 질문올립니다.Spring Boot : 2.7.9Java : 11application.propertiesspring.datasource.url= jdbc:h2:tcp://localhost/D:\\workspace\\study\\test spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=none spring.hellomyspring.domain.Memberpackage spring.hellomyspring.domain; import javax.persistence.*; @Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } spring.hellomyspring.controller.Memberpackage spring.hellomyspring.controller; public class Member { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } spring.hellomyspring.repository.JpaMemberRepositorypackage spring.hellomyspring.repository; import spring.hellomyspring.controller.Member; import javax.persistence.EntityManager; import java.util.List; import java.util.Optional; public class JpaMemberRepository implements MemberRepository{ private final EntityManager em; public JpaMemberRepository(EntityManager em) { this.em = em; } @Override public Member save(Member member) { em.persist(member); return member; } @Override public Optional<Member> findById(Long id) { Member member = em.find(Member.class, id); return Optional.ofNullable(member); } @Override public Optional<Member> findByName(String name) { List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class) .setParameter("name", name) .getResultList(); return result.stream().findAny(); } @Override public List<Member> findAll() { return em.createQuery("select m from Member m", Member.class).getResultList(); } } spring.hellomyspring.service.MemberServicepackage spring.hellomyspring.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import spring.hellomyspring.controller.Member; import spring.hellomyspring.repository.MemberRepository; import spring.hellomyspring.repository.MemoryMemberRepository; import java.util.List; import java.util.Optional; @Transactional public class MemberService { private final MemberRepository memberRepository; public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } public Long join(Member member){ // 같은 이름 중복 회원 x validateDuplicateMember(member); memberRepository.save(member); return member.getId(); } private void validateDuplicateMember(Member member) { memberRepository.findByName(member.getName()) .ifPresent(m -> { throw new IllegalStateException("이미 존재하는 회원입니다."); }); } // 전체회원 조회 public List<Member> findMembers() { return memberRepository.findAll(); } public Optional<Member> findOne(Long memberId) { return memberRepository.findById(memberId); } }
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
JdbcTemplate queryForMap 관련 질문이있습니다.
공부를 하다보니 궁금한게 있어서 질문 드립니다.만약JdbcTemplate를 사용해서sql = "select * from Table where id = :id";sql로 특정 id의 값을 사용해 테이블 값을 가져오고Map<String, Object> param = Map.of("id", id); 으로 정의하고Map<String, Obeject> result = template.queryForMap(sql, param);을 했을시에Object에는 sql문을 사용해서 검색한 데이터들이 들어가는 걸로 이해를 했는데그러면 String이라고 정해둔 key값에는 무엇이 들어가나요??
-
해결됨스프링 시큐리티
Principal 인터페이스와 User 클래스의 관계
안녕하세요. 강의를 듣던 중 해결되지 않는 의문이 생겨 질문드립니다.강의에서 Principal 은 인터페이스이며 UserDetailsService에서 반환한 User 클래스가 구현체로 사용된다고 말씀해주셨는데 여기서 의문이 생겼습니다.확인해보니 Principal은 User 클래스의 인터페이스가 아닌 Authentication 의 구현체로 사용되는 UsernamePasswordAuthenticationToken 의 최상위 인터페이스였습니다.하지만 Authentication에서 User 객체를 받아오는 메서드의 이름도 getPrincipal() 입니다. 그렇다면, 위 그림에서 나타난 Principal 인터페이스와 User 객체를 반환하는 getPrincipal()의 principal은 서로 다른 의미로 쓰이는 건가요?디버깅을 해봐도 아래와 같이 Principal 인터페이스를 구현하는 XxxAuthenticaionToken 객체가 Authentication 타입으로 받아지고 User 객체는 그냥 Object 타입으로 받아져서 혼동이 되어 질문드립니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HTTP 요청 메시지 로그로 확인하기
application.properties 에logging.level.org.apache.coyote.http11=debug똑같이 했는데웹브라우저가 인코딩해서 보내질 않습니다.Received [GET /hello?username=Kim HTTP/1.1(헤더 정보 부분은 다 나옵니다) 코드를 보면Unused property 라고 뜹니다.구글링을해도 나오질않네요..답변주시면 정말 감사하겠습니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
spring socket 통신
안녕하세요. 개발하다 궁금한 사항이 있어 질문드립니다.spring을 이용해 백엔드 서버를 구축하고 있는데 디바이스(안드로이드)와 http 통신, tcp/ip socket 통신 두가지를 모두 구현해야 합니다. 이럴 경우에는 java의 socket 관련 라이브러리를 사용해서 소켓 서버를 만들고 서블릿을 이용한 웹서버도 만들어 두 개를 동시에 실행시켜야 하는지 아니면 다른 방식으로 구현해야 하는지 문의드립니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
어디에 있나요??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]수업들으면 똑같이 따라하려 하는데 강사님께서 보는 화면의 이런 부분들은 어디에 나와 있는지 알수있을까요?? 사소산 질문이라 죄송합니다
-
미해결스프링 부트 - 핵심 원리와 활용
직접 만든 라이브러리의 경우 어떻게 배포 되는건가요?
[질문 내용]실무 경험이 없어 제 질문이 적절한지도 잘 모르겠습니다 ㅠㅠ제가 개인 프로젝트를 할땐 항상 코드만 배포 환경에 받고 그 환경에서 빌드 > 실행 과정을 했었는데요.이번과 같이 직접 만든 jar 파일의 경우엔 libs 폴더에 있는데 이 libs 폴더를 그냥 제 프로젝트에 포함되어 배포 하면 되는 건지(예를 들어 github라면 그냥 github에 libs 폴더의 jar 파일을 업로드해도 되는지) 아니면 보통 라이브러리로 만든다면 뭔가 저장소에 등록하는 과정을 필수로 해야 하는 건지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]영한님 강의를 들으면서 내용을 일부 수정해서 공부를 하고 있습니다 . 세션 부분인데요 영한님 강의에서는 JPA 를 사용하지 않았지만 저는 JPA 를 사용해보았습니다. 하지만 계속 WARN 11252 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.util.Optional' to required type 'project.PointWeb.Domain.Member'; Cannot convert value of type 'java.util.Optional' to required type 'project.PointWeb.Domain.Member': no matching editors or conversion strategy found] 이 에러가 발생해서 고민중입니다. Optional 이 문제인 것 같은데 어떻게 변경을 해야 할 지 모르겠습니다. 강의 내용을 조금 변경해서 실습을 하고 있어서 질문드릴까 고민했지만, 해결할 수 있는 방법을 찾지 못해서 질문 드립니다.... 감사합니다
-
해결됨스프링 핵심 원리 - 고급편
ThreadLocal 관련하여 질문드립니다.
spring webflux에서 비동기 통신을 한다면한쓰레드에서 블록킹되지 않고 다른 프로세스가 진행되는 것으로 알고 있습니다.webflux에서 threadLocal을 쓴다면 한 thread를 점유하는 의미가 없는것인지 질문드립니다.
-
미해결스프링 핵심 원리 - 기본편
에러부분이 나서 진행이 안되네요... 의존성 문제인거 같기도한데
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [C:\hello\core\out\production\classes\hello\core\order\OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}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.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93)at hello.core.scan.AutoAppConfigTest.basicScan(AutoAppConfigTest.java:15)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:566)at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)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:1541)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:1541)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:57)at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)... 83 more종료 코드 -1(으)로 완료된 프로세스 @Component public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired // 생성자에서 여러 의존관계도 한번에 주입받을 수 있다. public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; } @Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Member member = memberRepository.findById(memberId); int discountPrice = discountPolicy.disCount(member, itemPrice); return new Order(memberId , itemName, itemPrice ,discountPrice); } // 테스트 용도 public MemberRepository getMemberRepository() { return memberRepository; } } public class AutoAppConfigTest { @Test void basicScan() { ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class); MemberService memberService = ac.getBean(MemberService.class); assertThat(memberService).isInstanceOf(MemberService.class); // AnnotationConfigApplicationContext를 사용하는 것은 기존과 동일하다. // 설정 정보로 AutoAppConfig 클래스를 넘겨준다. // 설정해보면 기존과 같이 잘 동작하는 것을 확인할 수 있다. } @Configuration @ComponentScan( //자동으로 스프링 빈을 등록할 수 있는 기능 excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION ,classes = Configuration.class) ) public class AutoAppConfig { }빈을 찾기 못해서 발생하는 문제인건 알겠는데 어느부분인지는 모르겠네요ㅜㅜ
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Spring Boot 3.X distinct 관련
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화Spring Boot 3.2버전에서 실습 중에, distinct 옵션을 사용하지 않고도 distinct 옵션을 넣은 것처럼 Row가 2줄 출력됩니다. 이것저것 코드를 확인하다가 Spring Boot를 2.x 버전으로 내린 후에 다시 확인해보았는데, 그제서야 강의에 나오는 것처럼 중복 데이터 4개가 나옵니다. 혹시 이것 관련해서 jpa에서 업데이트가 된 것인지요..? 검색 능력이랑 문서 능력 찾아보는 능력이 딸려, 한참 찾아보다 여기에 질문합니다 ㅜㅜ 실례가 안된다면 이러한 내용을 어떻게 찾는지도 알게 될 수 있다면 좋을거 같습니다!
-
미해결실전! Querydsl
QueryDSL 에서 leftJoin & fetchJoin 후 lazy loading 이 되는 현상
영한님 안녕하세요, QueryDSL 공부 중 막히는 부분이 있어 질문드립니다.1:N 연관관계를 가지고 있는 두 엔티티 Team 과 Member 가 있을 때, QueryDSL 로 leftJoin & fetchJoin 으로 두 테이블을 조인하여 Member 목록을 조회하고 싶은데, 만약 Team 테이블에 FK 에 해당하는 row 가 존재하지 않는 경우에는 Member.team 에 그냥 null 이 들어있고 객체에 접근하더라도 추가적인 select 쿼리가 실행되지 않도록 하고 싶습니다. 그런데 제 바람과는 달리 Member.team 을 참조하는 시점에 lazy loading 이 되면서 select 쿼리가 실행되더라고요.실제 코드를 바탕으로 설명해보겠습니다.아래와 같이 1:N 연관 관계를 갖는 Team 과 Member 라는 엔티티가 있습니다.@Table(name = "member") @Entity class Member( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int = 0, @Column(name = "team_id") var teamId: Long? = null, @Column(name = "name") var name: String? = null, @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id", insertable = false, updatable = false, foreignKey = ForeignKey(name = "none")) val team: Team? = null, ) @Table(name = "team") @Entity class Team( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0, @Column(name = "name") var name: String? = null, )여기서 아래의 코드로 left outer join 쿼리를 실행합니다.val members = from(member) .leftJoin(member.team, team).fetchJoin() .fetch()DB 는 아래와 같이 데이터가 저장되어 있습니다.// team +----+-------+ | id | name | +----+-------+ | 1 | team1 | +----+-------+ // member +----+---------+------+ | id | team_id | name | +----+---------+------+ | 1 | 2 | John | +----+---------+------+그럼 저는 아래와 같은 Member 객체 하나로만 이루어진 List 를 얻을 수 있을 거라고 생각했고, team 변수에 접근할 때 select 쿼리 실행 없이 null 만을 반환할 것이라고 기대했습니다.{ "id": 1, "team_id": 2, "name": "John", "team": null }하지만 아래와같이 member 테이블을 lazy loading 하는 로그가 찍히네요.Hibernate: insert into team (id, name) values (default, ?) Hibernate: insert into member (id, name, team_id) values (default, ?, ?) Hibernate: select member0_.id as id1_7_0_, team1_.id as id1_9_1_, member0_.name as name2_7_0_, member0_.team_id as team_id3_7_0_, team1_.name as name2_9_1_ from member member0_ left outer join team team1_ on member0_.team_id=team1_.id Hibernate: select team0_.id as id1_9_0_, team0_.name as name2_9_0_ from team team0_ where team0_.id=?그런데 만약 DB 의 데이터 중 member 의 team_id 만 1로 변경하니 쿼리 후 member.team 에 접근하더라도 아래와 같이 lazy loading 하는 로그가 찍히지 않았습니다.Hibernate: insert into team (id, name) values (default, ?) Hibernate: insert into member (id, name, team_id) values (default, ?, ?) Hibernate: select member0_.id as id1_7_0_, team1_.id as id1_9_1_, member0_.name as name2_7_0_, member0_.team_id as team_id3_7_0_, team1_.name as name2_9_1_ from member member0_ left outer join team team1_ on member0_.team_id=team1_.id테스트에 사용한 코드는 아래와 같습니다.@DataJpaTest @Import(MemberService::class) // MemberService.listMembers() 에서 QueryDsl 로 쿼리를 합니다. class MyTest( private val sut: MemberService, private val em: EntityManager, ) : FunSpec( { beforeEach { val team = Team(name = "team1") em.persist(team) val member = Member( name = "John", teamId = team.id + 1, // 이것만 team.id 로 바꾸면 team 접근 시 select 로그가 찍히지 않습니다. ) em.persist(member) em.clear() } test("my test") { val members = sut.listMembers() members.shouldNotBeEmpty() val team = members.first().team println(team) } }, )어차피 조회한 엔티티에 변경을 가하지는 않을 것이라, Member 엔티티를 detach 시키고 team 에 접근하면 lazy loading 이 안될까 싶어서 해보았는데 여전히 lazy loading 이 되더라구요 ^^;일단 @QueryProjection 을 붙인 별도의 DTO 를 정의해 아래와같이 쿼리하는 식으로 해결하려고 하는데 더 좋은 방법은 없을까요?class MemberDto @QueryProjection constructor( val id: Int, val teamId: Long? = null, val name: String? = null, val teamName: String? = null, ) @Service @Transactional(readOnly = true) class MemberService : QuerydslRepositorySupport(Member::class.java) { private val member = QMember.member private val team = QTeam.team fun listMembers(): List<MemberDto> { val members = from(member) .select(QMemberDto(member.id, member.teamId, member.name, team.name)) .leftJoin(member.team, team) .fetch() return members } }감사합니다.
-
미해결실전! 스프링 데이터 JPA
스프링 데이터 JPA의 구현체 질문
안녕하세요 김영환 강사님 항상 잘 듣고 있습니다. 다름이 아니라 스프링 데이터 JPA의 구현체 분석 파트 중 질문 사항이 있습니다.페이징에 대해서 처리할 때 마지막 파라미터로 Pageable 를 넘기게 되면 해당 정보로 자동으로 페이징 처리를 하게 된다고 알고 있습니다.어떻게 이게 가능한 것입니까? 이를 구현한 구현체를 찾아보려 하지만 찾지 못해 질문드립니다.!
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
localhost:8080/hello 오류에 관해 질문 드립니다
index까지는 되는데 /hello 열면 화이트라벨 에러가 발생합니다 왜 그런지 모르겠습니다
-
미해결스프링 핵심 원리 - 기본편
java.lang.IllegalStateException: Failed to load ApplicationContext
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)java.lang.IllegalStateException: Failed to load ApplicationContext 라고 계속 뜨는데 왜 실패하는 지 모르겠습니다.. 어떤걸 해결해야 테스트가 완료될까요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
35강 리팩토링 중에서 질문입니다.
안녕하세요 강사님, 제가 이제 막 개발을 시작한 신입이다보니 db와 자바가 아직 서툴어서 굉장히 이상한 질문을 드리는 것 같은데요.강의 7분..쯤, 도메인 계층에 비지니스 로직을 구현하면서 User 객체에서 작성된 returnBook()메소드관련 질문입니다. 반납을 위해서 Service에서 찾은 유저의 대출 히스토리에서 targetHistory를 찾기 위해 stream()이 시작되고, UserLoanHistory 객체를 필터링하는 중에, ".findFirst()"로 필터를 하신 이유를 문의드립니다.왜 마지막이 아니고, 첫번째를 찾나요?
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
프로필 설정
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]ItemServiceApplication을 실행해야 TestDataInit이 빈으로 등록되어 초기 데이터가 저장되는 것 아닌가요?그렇다면 테스트 코드 실행시 TestDataInit이 빈으로 등록되지 않아서 초기 데이터가 저장되지 않을 것 같은데 TestDataInit의 프로필 설정을 따로 하는 이유가 뭔가요??잘못 알고 있는 부분이 있다면 피드백 부탁드립니다.
-
미해결스프링 핵심 원리 - 기본편
memberRepositroy() 질문있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. AppConfig에서 순서는 보장되지 않는다하셨는데return new MemberServiceImpl(memberRepository())return new OrderServiceImpl(memberRe~~~,dis~~)이부분에서 memberRepository() 메서드를 빼고직접 new MemoryMemberRepository()를 넣으니까서로 다른 객체를 생성하더라구요 ( @Configration 사용한상태 )Configration 애너테이션을 사용해도하나의 메서드로 안빼고 직접 객체를 생성하면스프링컨테이너가 CGLIB?를 통해찾지못하는건가요?
-
미해결스프링 핵심 원리 - 기본편
단축키 cnt+alt_m 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 메서드 추출 단축키를 제목처럼 실행해도 아무것도 안뜨네요.. 키맵들어가도 이게 맞는데 왜이럴까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
준영속 관련 질문있습니다.
OrderService에서 order메소드에 public Long order(Member member, Item item) 이런식으로 id가 아닌 엔티티 객체를 바로 받는 식으로 제 개인 프로젝트에서 비슷한 방식으로 해봤습니다.Question과 member가 서로 양방향 매핑관계이구요public class Question { @Id @GeneratedValue @Column(name = "question_id") private Long id; private String title; private String content; private String username; @CreationTimestamp private LocalDateTime dateTime; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; public void setMember(Member member) { this.member = member; member.getQuestionList().add(this); } }public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String emailId; private String username; private String password; private int age; @OneToMany(mappedBy = "member") private List<Question> questionList=new ArrayList<>();OrderService에서 question을 save할 때 public Question save(Member member,Question question) { question.setMember(member); question.setUsername(member.getUsername()); question.setTitle(question.getTitle()); question.setContent(question.getContent()); questionRepository.save(question); return question; }failed to lazily initialize a collection of role: post.study.entity.Member.questionList, could not initialize proxy - no Session(제 개인 프로젝트라 엔티티 경로가 다릅니다.)이런식으로 에러가 나더라구요. 이게 controller 단에서 들어온 엔티티라 해당 서비스 트렌젝션 내에서는 JPA가 관리해주지 않는 준영속 상태 같은 개념인 것 같은데 정확하게 개념이 잡히지 않아서 질문드립니다.public Question save(Long memberId, Long questionId) { Member member = memberRepository.findById(memberId).get(); Question question = questionRepository.findById(questionId).get(); question.setMember(member); question.setUsername(member.getUsername()); question.setTitle(question.getTitle()); question.setContent(question.getContent()); questionRepository.save(question); return question; }id값을 받아서 해당 서비스 트렌젝션 내에서 직접 엔티티를 조회해야 같은 트렌젝션 내에서 엔티티가 JPA에 의해 관리되서 그런건가요? 개념을 정확히 잡고 싶습니다!