묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Repository 어노테이션
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네[질문 내용]@Repository 어노테이션을 처음 보는데 어느 강의에서 자세하게 볼 수 있을까요??
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
fetch join VS fetch join 페이징 궁금증
강의 영상 24분쯤 fetch join은 페이징 처리가 불가능하다고 말씀해주셨는데(사용하게 될 시 메모리에 임시로 모든 데이터 적재 후 페이징 처리로 설명), 페이징을 하지 않을 경우에도 Order rows가 1만건 이라면 1만건 모두 조회되는 것 아닌가요?이럴 때도 메모리에 대한 문제가 있을 것 같은데 제가 잘못 이해한 것인지 설명 부탁드리겠습니다!
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
도메인 로직에 대해서 궁금한 것이 있습니다.
현재 Member 도메인 모델 확장 까지의 수업을 듣고 궁금한 것이 있습니다! 저희가 이번 수업을 포함하여 지금까지 요구사항(도메인) -> 도메인 모델(회원) -> 비밀번호 해시라는 일련의 과정을 통해 비밀번호 암호화와 관련한 도메인 모델의 규칙, 속성, 행위 등을 뽑아냈기 때문에 비밀번호 암호화까지 도메인 로직에 포함된다고 이해했습니다. <인터페이스 위치를 결정하는 기준에 대해> 해당 답변에서도 PasswordEncoder를 어디에 둘지 결정할 때 사용한 기준은 도메인 모델을 이야기할 때 이게 등장하는가 라고 말씀해주시기도 했고요! 그렇다면 개발은 결국 요구사항을 토대로 진행되는 것이기에 모든 코드가 도메인 로직으로 분류되어야 하는 것 아닌가? 하는 의문점이 생겼습니다! 토비의 생각을 듣고 싶습니다!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
양방향 연관관계 알아보는 법?
안녕하세요. 8분쯤 양방향 연관관계 시 @JsonIgnore 어노테이션을 통해 순환 참조가 되는 것을 방지해야 한다고 알려주셨는데, 엔티티 하나하나 들어가서 직접 확인해야 하나요?ERD나 관계가 복잡해서 까먹을 경우 이렇게 하나씩 확인을 해야 하는지, 아니면 IDE 같은 걸로 도움을 받을 수 있는지 궁금합니다.
-
해결됨RabbitMQ를 이용한 비동기 아키텍처 한방에 해결하기
안녕하세요 섹션2. 12번 강의에서 질문 있습니다.
안녕하세요 강의 잘 듣고 있습니다. 섹션2 12번 강의에서 (관심사기반의뉴스레터발행/구독모델) 에서 질문 있습니다.fanout exchange는 바인딩된 모든 큐에 메시지를 보내는 방식이므로 모든 큐에 메시지가 가는 것으로 알고 있습니다.예를 들어 제가 java 라는 특정 topic을 구독하면 java queue 에 있는 메시지만 계속 소비할텐데, 그러면 나머지 spring queue나 vue queue 에는 메시지가 계속 쌓여 문제가 되는 것 아닌가요 ?발행/구독 모델을 왜 fanout exchange로 구현하신 건지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
16강 17강 간단 정리 이게 맞을까요 ?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. 좋은 강의 잘 수강하고 있습니다. 16강과 17강 강의가 저에게는 이해하기 어려워서 다음과 같이 정리해보았습니다. 맞게 잘 적은건지 피드백 부탁드리겠습니다 ! 엔티티의 XxxToOne 관계는 모두 패치조인 한다.row 수를 증가시키지 않기 때문이다. XxxToMany(컬렉션)는 페이징을 하지 않고 조회되는 데이터가 적을 시에는 패치조인을 해도 된다. 단, N 쪽에 수 많은 데이터가 있다면 성능 최적화를 고려해야 하기 때문에 페이징 기법을 사용할 수 있으니 패치조인은 사용하지 말자 왜냐하면 모든 데이터를 DB에서 읽어오고, Hibernate는 1:N 조인 결과를 모두 메모리에 가져온 다음 1을 기준으로 페이징을 메모리에서 다시 수행해야 한다.이때, 수백만개의 데이터라면 애플리케이션은 메모리 부족으로 OOM이 발생할 수 있다. 컬렉션은 지연 로딩으로 조회하는데 성능 최적화를 위해 hibernate.default_batch_fetch_size, @BatchSize를 적용한다. IN 쿼리를 통해 한꺼번에 설정한 size 만큼 조회할 수 있다. 장점 : row 수가 많아지는 단점을 가진 패치 조인보다 DB 데이터 양이 최적화 된다.
-
미해결[2탄] 옆집 개발자와 같이 진짜 이해하며 만들어보는 첫 Spring Boot 프로젝트
강의 자료 부탁드립니다.
강의 자료 제공이라고 하셨는데 강의 자료가 없습니다. 미리 올려 주시면 좋을 것 같습니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
Auto Increment 질문
안녕하세요 토비님. 강의 정말 잘 보고 있습니다.다름이 아니라 Auto Increment 전략을 현업에서도 자주 사용하시는지 궁금해서 문의드립니다. Mysql에서 Auto Increment를 사용하니 bluk insert가 안되는 구조던데 문제가 있으셨던 적은 없는지 궁금합니다. bluk insert를 jdbc template으로 구현했더니 갈레라 3중화 구조라 ID가 3씩 증가하는 문제가 있어서 곤란한 경험이 있습니다. 이럴 경우 ID 전략을 UUID나 Snowflake 이런식으로 가져가야 하는지 궁금합니다.아니면 다른 해결 방법이 있으시다면 알려주시면 감사하겠습니다.
-
해결됨Spring Boot와 React로 배우는 초간단 REST API 게시판 만들기
스프링 기동 하는 부분에서 계속 에러가 나와서 질문 드립니다.
안녕하세요. 스프링 기동 부분에서 에러가 나와서,자바 버전도 바꾸어 보고, 인텔리제이도 최신 버전으로 업데이트 하고 , 여러 가지 시도를 해보는데, 문제가 해결이 안되고 있습니다.여기 에러 로그를 남겨 봅니다. 참고로 그래이들 빌드시엔 에러가 안 나오지만, 소스의 메인 메서드를 실행하면 에러가 나옵니다. Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.2025-06-25T19:32:28.071+09:00 ERROR 10688 --- [prac] [ main] o.s.b.d.LoggingFailureAnalysisReporter :***************************APPLICATION FAILED TO START***************************Description:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver classAction:Consider the following:If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).> Task :restapi.prac.PracApplication.main() FAILEDExecution failed for task ':restapi.prac.PracApplication.main()'.> Process 'command 'C:\Users\jjhgw\.jdks\openjdk-24.0.1\bin\java.exe'' finished with non-zero exit value 1* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.> Get more help at https://help.gradle.org.BUILD FAILED in 14s3 actionable tasks: 2 executed, 1 up-to-date
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
데이터 초기화 시 CASCADE 옵션 궁금증
안녕하세요. PostConstruct 어노테이션을 사용해 Spring이 초기화될 때 DB에 데이터를 초기화 해주셨는데요. Order, OrderItem 클래스 필드에 cascade 옵션이 있어서 order나 orderItem만 em.persist() 하면 다른 엔티티도(delivery, orderItems 등) 다 같이 persist 되지 않나요? 왜 엔티티별로 따로 하나씩 persist 하셨는지 궁금합니다. 제가 잘못 이해한 거라면 설명 한번 부탁드리겠습니다!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
order.getOrderItems() 시 필드 접근 안했는데 select문이 나가는 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요.강의 자료에 orderItems.stream().forEach(o -> o.getItem()).getName()); // LAZY 강제 초기화라고 적혀있어서 그 위의 코드인 List<OrderItem> orderItems = order.getItems()에서는 DB에 SELECT 쿼리를 보내지 않는구나라고 이해했습니다. 근데 확인해보니 아래 코드를 PostMan으로 테스트를 해보았더니 orderItems : null 이지만SELECT절을 통해 데이터를 조회한 결과를 보였습니다.또한, order.getOrderItems()를 하지 않아도 orderItem을 조회하는 SELECT절이 나가더라구요 .. @GetMapping("/api/v1/simple-orders") public List<Order> ordersV1() { List<Order> all = orderRepository.findAllByString(new OrderSearch()); for (Order order : all) { order.getMember().getName(); // LAZY 강제 초기화 => 예외 발생 안함 ! why? Open Session in View(OSIV) 때문에 order.getDelivery().getAddress(); // LAZY 강제 초기화 => 예외 발생 안함 ! why? Open Session in View(OSIV) 때문에 order.getOrderItems(); // ? } // 원래는 LazyInitializationException이 발생하는게 정상이지만 OSIV로 인해 발생하지 않음 return all; } 다른 질문을 참고하였을 때 David님께서 아래와 같은 답변을 해주셨습니다.안녕하세요. Jeongmin Lee님:), 공식 서포터즈 Taewon David Hwang입니다.지연로딩(Lazy Loading)은 엔티티의 애트리뷰트에 접근할 때 데이터를 가져옵니다.그러나 하이버네이트에서 지정한 기본타입에 해당되는 것들은 기본적으로 지연로딩을 허용하지 않습니다.따라서 OrderItem의 애트리뷰트인 name, price, stockQuantty 중 하나라도 접근하게 되면 기본타입에 해당하는 name, price, stockQuantity의 데이터를 모두 불러오게 됩니다.David 선생님 의견에 따르면 엔티티의 에트리뷰트에 접근해야 데이터를 가져오는거 같은데 왜 위 사진같이 DB에 SELECT절을 호출 해 데이터를 가져오는건가요?
-
해결됨RabbitMQ를 이용한 비동기 아키텍처 한방에 해결하기
안녕하세요 "섹션2 8. Consumer간 작업 분배" 에서 질문 있습니다.
안녕하세요. 강의 잘 듣고 있습니다.섹션2. 8번 강의 11분 13초 쯤에 하시는 말씀에 의문이 들어 질문글 남깁니다. 이 부분 설명하실때 ' 컨슈밍을 할때 파라미터로 받은 초를 슬립을 준 뒤에 소진을 하겠다' 라고 하셨는데, 메시지를 받은 순간 이미 소진이 시작 된 것이고 각각 2초 4초 5초뒤에 소진이 끝나는 것 아닌가요? 조금 헷갈려서 질문 드립니다.좋은 강의 감사드립니다.
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
빌드 안 되시는 분들 참고
Maven resources compiler 어쩌구자바 버전 문제제 기준 pom.xml에서 java.version 21로 올리고 프로젝트 설정에서 SDK/모듈도 동일하게 설정했더니 해소 됐습니다NoSuchFieldError 어쩌구lombok 버전이 자바 버전과 안 맞음.pom.xml lombok dependency의 버전을 자바랑 맞추기 https://jinseobbae.github.io/java/2023/02/27/lombok-version-compatibility.htmlUnsupported class file major version 65스프링부트 버전 문제3.3.0으로 올리니까 해소됐습니다
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
MSA 환경에서 도메인 모델의 정의 범위에 대한 질문
안녕하세요, 토비님.도메인 모델의 정의 범위에 대해 토비님의 생각이 궁금하여 질문드립니다. 현재 저는 MSA 환경에서 여러 시스템이 나뉘어 있는 구조에서 일하고 있습니다. 보통 팀에서는 “우리가 생성·저장하는 데이터 구조”를 도메인 모델로 이해하는 경우가 많은데요,저는 도메인 모델의 범위가 그보다 더 넓다고 생각하고 있습니다. 예를 들어, 주문시스템이 있다고 할 때, 주문시스템은 주문데이터를 생성/관리하는 책임을 지겠지만 이를 위해서여러 시스템(상품, 프로모션, 결제 등)에서 데이터를 조회해 조합하여 업무 규칙을 수행하는 책임을 가질 수 있습니다. 이 경우, 다른 시스템이 생성·관리하는 개념이라 하더라도,주문시스템 내부에서의 목적과 규칙에 따라 주문에 맞는 방식으로 추상화된 모델을 정의하는 것이바로 도메인 모델이라고 생각하는데요. 즉, 외부 개념이라도 주문시스템의 책임 하에 있는 로직과 규칙이 있다면, 그것은 주문의 도메인이다라는 관점입니다. 이와 같은 관점에 대해 토비님은 어떻게 생각하시는지,도메인 모델 정의의 기준에 대해 의견을 듣고 싶습니다. 감사합니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
테스트 준비 과정에서 서비스 메서드 호출
@Test void find() { Member member = memberRegister.register(MemberFixture.createMemberRegisterRequest()); entityManager.flush(); entityManager.clear(); Member found = memberFinder.find(member.getId()); assertThat(member.getId()).isEqualTo(found.getId()); }현재 코드에서 위와 같이 테스트에서 회원 저장을 위해 memberRegister.register를 호출하고 있습니다.그런데 memberRegister.register에는 단순히 회원을 저장하는 것 외에도 이메일 전송 같은 부가적인 로직이 포함되어 있습니다. 이러한 부가적인 로직때문에 테스트 속도가 느려진다던가, 테스트가 실패하는 원인이 될 수 있다고 생각이 들었습니다.이처럼 테스트 준비에 필요하지 않은 부가 로직까지 수행되는 상황에서, memberRegister.register를 테스트 준비 용도로 사용하는 것이 적절한지 토비님의 생각이 궁금합니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
도메인 모델에서의 검증과 애플리케이션 레벨 검증의 경계
도메인 모델에서의 검증과 애플리케이션 레벨 검증의 경계에 대해 질문드립니다.현재 도메인 모델에서는 이메일 형식이 올바른지, 닉네임이나 비밀번호가 null이 아닌지 같은 최소한의 조건만 검증하고 있습니다. 반면, 비밀번호가 8자 이상인지, 닉네임이 5자 이상인지 같은 검증은 애플리케이션 레이어에서 처리하고 있습니다. 그런데 닉네임이 5자 이상이어야 한다 같은 규칙도 도메인 규칙으로 볼 수 있지 않을까 라고 생각이 들어 해당 검증 역시 도메인 모델에서 처리하는게 맞지 않나 라는 생각이 드는데,도메인 모델에서의 검증과 애플리케이션 레벨 검증의 경계는 어디까지 두는 게 좋은지 토비님 의견이 궁금합니다.말씀하신것을 토대로 예측해 봤을때 형식이나 정책적 요구사항(변경 가능성이 있는 규칙)은 애플리케이션 레이어에서, 도메인의 본질적 불변 조건은 도메인에서 검증하는 걸까요?
-
미해결실전! Querydsl
querydsl 설정 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]여기에 질문 내용을 남겨주세요. autoplugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' } group = 'study' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //test 롬복 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } clean { delete file('src/main/generated') } 교안에 나온 대로 설정해 준 상태인데 현재 q타입 클래스는 생성 되었지만 intellij가 이를 정상적인 클래스로 인식하지 못해서 QHello를 import하지 못하고 있는 상황입니다
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
Member#register() 메서드명이 모호하게 느껴집니다.
Member#create() 메서드를 register로 공통언어를 바꾸셨는데, 뜻이 모호해진 것 같아서 질문드립니다! 제가 생각하기에 register(등록)이라는 단어는 생성과 영속화라는 두가지의 행위를 함축한 단어로 느껴집니다. 따라서 MemberService#register()는 너무 자연스럽습니다. 실제로 Member를 생성한 후에 MemberRepository를 통하여 영속화까지 하는 내용으로 구현되어있습니다.하지만 Member#register()는 이와 다르게 Java 객체를 생성하기만 하는 것이라, 메서드명과 실제 동작이 불일치한다고 느껴집니다. 하지만 또 동시에 도메인 모델을 글로 작성하는 과정에서 '멤버를 등록한다.' 라는 말을 쓰는 것은 자연스럽습니다. 그 구현이 코드적으로 Member에 있는 것만이 부자연스럽습니다.이런 경우에는 Member라는 객체만으로 도메인 모델을 온전히 표현해내기가 어려운 것일까요? 해당 모델을 표현하기 위해서는 MemberService 같은 코드가 꼭 필요한 걸까요?
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
EntityManager#flush()를 검증하면 더 좋을 것 같습니다!
멤버를 저장하는 테스트에서 EntityManager#flush()를 호출해서 플러시되어 DB까지 쿼리문이 제대로 가는지 검증하시는 것을 보았습니다. (저는 플러시까지 테스트해볼 생각을 못했어서 아주 인상깊었습니다 ㅎㅎ) 하지만 해당 부분이 검증문 없이 홀로 호출되고 있습니다.좀더 의도를 드러내기 위해서는 assertThatCode(() -> em.flush()).doesNotThrowAnyException() 처럼 코드를 작성하는게 더 좋지 않을까 싶어서 질문드립니다!적용 예시@Test void 멤버를_저장한다() { var member = MemberFixture.createAny(); memberRepository.save(member); assertThat(member.id()).isNotNull(); assertThatCode(() -> em.flush()) .doesNotThrowAnyException(); }
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
테스트클래스명이 테스트 목적을 잘 나타내지 못하는 것 같습니다.
MemberRepositoryTest는 EntityManager 나 @DataJpaTest 등 Jpa와 깊게 관련되어있는 테스트로 이해됐습니다. EntityManager#flush() 가 잘 호출되는지 확인하는 부분도 그런 이유에서 이해됩니다.하지만 테스트명이 MemberRepositoryTest인 점에서 헷갈리는 부분이 발생합니다. MemberRepository 인터페이스의 메서드를 테스트하는 것이 목적이라면 좀 더 추상화된 테스트를 작성하는 것이 옳지 않았나? 라는 것이 주된 궁금증입니다. 물론 Spring Data JPA 특성상 런타임에 구현체가 만들어지기 때문에, 테스트 대상은 인터페이스를 사용해야 한다는 것은 이해합니다만, 최소한 클래스명은 좀 더 구체적으로 작성해주는 것이 의도에 부합하지 않나? 해서 질문드립니다! 어떻게 생각하시나요?