MemberRepositoryTest는 EntityManager 나 @DataJpaTest 등 Jpa와 깊게 관련되어있는 테스트로 이해됐습니다. EntityManager#flush() 가 잘 호출되는지 확인하는 부분도 그런 이유에서 이해됩니다. 하지만 테스트명이 MemberRepositoryTest인 점에서 헷갈리는 부분이 발생합니다. MemberRepository 인터페이스의 메서드를 테스트하는 것이 목적이라면 좀 더 추상화된 테스트를 작성하는 것이 옳지 않았나? 라는 것이 주된 궁금증입니다. 물론 Spring Data JPA 특성상 런타임에 구현체가 만들어지기 때문에, 테스트 대상은 인터페이스를 사용해야 한다는 것은 이해합니다만, 최소한 클래스명은 좀 더 구체적으로 작성해주는 것이 의도에 부합하지 않나? 해서 질문드립니다! 어떻게 생각하시나요?
해당 코드에서 자기 자신의 프로필 address와 비교하는 로직을 도메인에게 맡기는 건 어떨까요? 토비님! 이렇게 해도 되는건지 아니면 따로 빼신 이유가 있으신 지 궁금합니다. private void checkDuplicateProfile(Member member, String profileAddress) { if (profileAddress.isEmpty()) return; Profile currentProfile = member.getDetail().getProfile(); if (currentProfile != null && currentProfile.address().equals(profileAddress)) return; if (memberRepository.findByProfile(new Profile(profileAddress)).isPresent()) { throw new DuplicateProfileException("이미 존재하는 프로필 주소입니다: " + profileAddress); } } 이런 식으로요! private void checkDuplicateProfile(Member member, String profileAddress) { if (profileAddress.isEmpty()) return; if (!member.isProfileNull() && member.isProfileEquals(profileAddress)) return; if (memberRepository.findByProfile(new Profile(profileAddress)).isPresent()) { throw new DuplicateProfileException("이미 존재하는 프로필 주소입니다: " + profileAddress); } }
안녕하십니까 강사님. 강의를 잘 듣고있던 중에 질문이 생겨서 드립니다. AsyncExcutor의 설정값을 설정하는 부분에서 서비스 앞단에서 대고객 트래픽을 받을때 maxPoolSize를 무한으로 설정하고, 큐의 크기를 0으로 두어서 빠르게 스레드를 생성하여 요청을 처리한다고 하셨습니다. 또한 그 설정을 한 스레드 풀의 작업들은 대체로 레디스 캐싱된 값을 뿌려주는것과 같이 응답시간이 빠르게 보장된 요청의 경우에 위와같은 설정값을 설정한다고 이해했습니다. 실제 실무에서 위와같이 설정해도 무한대까지 스레드가 생기지는 않으니 문제가 없다?고 하신것 같은데 그 이유가 잘 이해가 안되는 것 같습니다. 제 나름대로 추론을 해봤는데요. 우선 redis에 캐싱된 결과를 뿌리는 요청을 예로 들어서 보면, I/O 바운드 작업이므로 스레드가 빠르게 증가하여 요청을 처리하는게 중요하고, 스레드가 증가하더라고 CPU 사용량의 증가가 CPU 바운드 작업처럼 크게 증가하지 않을것이다. 따라서 스파이크 트래픽이 발생해도 서버가 죽거나 문제가 생기지는 않을것이다. 이렇게 생각을 해봤는데 좀 더 정확한 답변을 듣고싶어서 질문드립니다!
안녕하세요, 토비님. 주니어로서 아직 부족한 점이 많지만, 궁금한 점이 있어 또 이렇게 질문드립니다. Section 3에서 소개된 splearn 도메인 강의를 듣기 전에, 스스로 먼저 도메인 모델링을 해보는 시간을 가졌습니다. 그 과정에서 회원 , 수강 , 강의 등의 개념 외에 수강신청 이라는 도메인을 도출했는데요, 그 이유는 “수강은 수강신청 후 결제가 완료되어야 성립된다” 는 제 안의 암묵적인 경험에 의한 도메인 해석 때문이었습니다. 그런데 사실 강의에서 제시된 사용자 스토리에는 결제 라는 개념이 존재하지 않았습니다. 그럼에도 불구하고, 과거 경험에서 비롯된 도메인이 자연스럽게 설계에 스며들었고, 결과적으로 오버엔지니어링으로 이어졌다 는 생각이 들었습니다. 이런 식의 ‘의도되지 않았지만 그럴듯한 도메인’ 을 설계에 넣고 싶은 유혹은 실제 회사에서 설계할 때도 자주 느끼는 부분입니다. 그래서 토비님께서는 이런 상황에서 어떤 기준으로 도메인을 포함하거나 배제하시는지, 그리고 본인의 경험을 어떤 방식으로 설계에 녹이시는지 가 궁금해졌습니다. 바쁘시겠지만, 짧은 의견이라도 들려주시면 큰 도움이 될 것 같습니다. 감사합니다!
안녕하세요 토비님, 강의 너무 재미있게 듣고 있습니다. 인터페이스를 도메인 계층에 둘지, required 포트에 둘지 결정하는 기준이 있을까요? Splearn의 코드를 예로 들어보면, 도메인 서비스 인터페이스인 passwordEncoder 는 어댑터 계층에서 구체적인 기술로 구현된다는 점에서 EmailSender , MemberRepository 같은 required 포트의 인터페이스와 유사하게 느껴집니다. 이들 모두 외부 세계(또는 특정 기술)와 애플리케이션을 분리하는 역할을 하기 때문입니다. 만약 애플리케이션 서비스에서 passwordEncoder 를 사용해 비밀번호를 암호화한 후, 암호화된 비밀번호( passwordHash )를 Member.register 메서드에 인자로 직접 넘겨준다면, passwordEncoder 역시 required 포트에 위치할 수 있지 않을까요? 도메인 계층도 애플리케이션 서비스에 의존하지 않게 되고요. 그런데도 불구하고 passwordEncoder 를 도메인 계층의 인터페이스로 두신 이유가 궁금합니다. 감사합니다.
안녕하세요, 토비님. 메서드 파라미터가 많아질 경우 record 타입의 parameter object를 사용하여 가독성을 높일 수 있는 방법을 소개해주셨는데요, 이 방법으로도 parameter object 인스턴스 생성 시 argument를 잘못 전달한다거나 등의 휴먼 에러는 여전히 발생 가능하지 않나 생각이 듭니다. java record도 kotlin의 named parameter와 같은 기능을 제공하면 좋겠지만 검색해봤을땐 아직 제공하지 않는 것 같더라구요. 이처럼 argument 전달 버그는 예방할 방법이 없을까요? 혹은 강의 뒷부분에서 이러한 점을 개선해주실까요? record에 builder를 사용해야 하나 생각이 들긴 하는데, 괜찮은 방법인지는 물음표네요.
안녕하세요. 영한님 궁금한 점이 있습니다. sleep(10) 를 하면 동시 실행을 더 촉진할 수 있다는 것이 이해가 안됩니다. 예를 들어, 아래를 가정한다면요! 각 시간은 별도로 가정한 것입니다. 1번 쓰레드가 1.0초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.1초에 실행 가정, 2번 쓰레드가 1.1초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.2초에 실행 가정, 3번 쓰레드가 1.2초에 먼저 실행이 된 후 0.1 초 쉬었다가 실행이 되면 1.3초에 실행 가정, ... 그렇다면 각 쓰레드가 0.1초씩 쉬었다고 하더라도 결국에는 실행시점이 1.1초, 1.2초, 1.3초 다 다르다고 봐도 되지 않나요? 뭔가, sleep(10) 을 빠지게 되면 대부분 쓰레들이 비슷한 시점에 10ms 를 자고, 거의 동시에 깨어나서 increment() 를 실행하는 것 같은데 맞나요? 맞다면 왜 그런가요? 감사합니다!
안녕하세요. 좋은 강의 항상 감사합니다. for문으로 1부터 100부터 돌건데, 그 i 변수값(카운터)이 바깥의 공유 변수에 그대로 대입(이퀄 연산) 하는데. 이런 쓰레드가 있는데 100개가 있는데 동시에 같은 로직으로 동일한 공유 변수에 접근을 하는 상황이다. 더하기 연산을 하는 것이 아니다. 이 프로그램이 끝나면 이 공유변수에는 몇의 값 ? i = 1 처럼 원자적 연산일 경우, 멀티스레드 환경에서 문제가 되지 않는다고 하셨잖아요. 그러면 위의 상황에서도 무조건 100이 들어간다고 봐도 되죠? 실제로 테스트 해봤을 때도 100이 계속 들어가긴 합니다. 감사합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] -a---- 2025-06-22 오후 4:15 22515429 hello-spring-0.0.1-SNAPSHOT.war gradlew 실행하고 폴더를 이동했더니 war 파일 밖에 없습니다. jar 파일이 없는거면 처음부터 잘못된건가요?
안녕하세요. 토비님 강의가 마치 의도하신 것 처럼 시니어 개발자님과 함께 개발하면서 의논하는 느낌으로 진행되어서 재밌게 잘 수강하고 있습니다. 강의 내용에서 DDD는 도메인이 복잡해진 순간에 택해야 한다. 라는 말씀을 해주셨는데요. 문득, "토비님이 생각하시는 도메인이 복잡해진 순간은 어떤 순간일까? 나름의 기준이 있으신걸까?" 하는 생각이 들었습니다. 개인적으로 저는 어떻게 생각할까 라고 고민을 해봤는데요. 1) 도메인을 설명하기 위해서 개발자가 코드를 살펴봐야 하는 순간 2) 각 도메인 간의 결합도가 고객의 유스케이스를 해결하기 위해 다양하게 결합되어야 하는 경우 이 두 가지가 떠올랐는데, 토비님의 견해가 궁금해서 질문드려봅니다! 늘 양질의 강의를 제공해주셔서 감사드립니다. (_ _)
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/ 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예 [질문 내용] 강의 내용대로 설정했는데 qtype이 만들어지고 있지 않습니다 스프링부트 버전이 올라가고 나서 qtype설정이 바뀐거 같은데요 추가 내용을 올려주셨으면 좋겠어요 ㅠㅠㅠ
안녕하세요 토비님, 강의 너무 잘 듣고 있습니다. 이메일 패턴 테스트 관련해서 궁금한 부분이 생겨 질문을 드립니다. 해당 강의를 기준으로 기존 : Member 엔티티에서 패턴 검증 변경 후 : Email 값객체에서 패턴 검증 변경 후 단계에서 Email 값 객체에 패턴 검증하는 로직이 들어갔기에 해당 로직에 대한 테스트는 EmailTest 에 들어가야 하지 않는가? 라는 생각이 들어요. 해당 부분에 대해 의견을 여쭙고 싶습니다. 감사합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] db는 연결이 되어있다고 하는데 막상 db콘솔에서 insert한 데이터가 웹 페이지 회원 목록 조회에서는 안뜹니다. 막상 회원가입을 하면 목록에 뜨는 상황입니다. 그리고 db를 끊어도 웹 페이지에서 회원 가입과 회원 목록 조회는 됩니다. 그리고 db를 연결한 상태에서 웹 페이지에서 회원가입을 하면 db에는 넘어온 정보가 없습니다
안녕하세요 토비님! 강의 너무 잘듣고 있습니다. 애그리거트 쪽 강의를 들으면서 문득 든 생각을 질문드립니다. 현재 사내에서 하고 있는 프로젝트는 JPA를 전혀사용하지 않고 Mybatis만을 사용하고 있는데요 이런 경우에도 에그리거트라던가 헥사고날 아키텍쳐를 적용하면서 진행하는게 충분히 가능할까요? 그게 아니라면 기존에 적용하고 있는 흔히 말하는 레이어드 아키텍쳐 및 트랜잭션 스크립트 방식으로 진행하는게 더 나은 방법일까요? 혹시라도 수준 떨어지는 질문이라면 사과드립니다. 감사합니다.
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 강의 마지막 즈음에 익명클래스를 사용할 수 없을 때의 예시로 Printer printer1 = new LocalPrinter(); printer1.print(); Printer printer2 = new LocalPrinter(); printer2.print(); 라는 두개의 코드를 보여주셨는데 사용할 수 없다는 게 사용할 수 없게 막혀있다는건지.. 이렇게 같은 객체를 생성할 때는 사용하지 말라는건지 이해가 안되네요 위 코드를 사용할 수 없는게 아니라 이해가 잘 안됩니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 다름이 아니라 3:38쯤에 옆에 아이콘을 누르면 약간 확장이 되는 기능이 제 인텔리제이에서는 보이지가 않아서요. 어떻게 설정을 하는걸까요?
외부 API를 호출해서 DB에 적재하는 배치를 구성을 하려고한다. 이때까지 문서 내용을 바탕으로는 Chunk가 아닌 Tasklet으로 해도 문제가 없다고 판단이든다. 하지만 공공 데이터 API를 1번 호출 할 때 10건씩만 데이터를 조회해야한다는 단점이있다. 평소에 하루에 1번 호출하겠지만 지난 3달의 데이터를 일단 적재를 해야한다. 이런 상황에서도 RepeatStatus.CONTINUABLE 이 아닌 while문으로 계속 호출하고 끝나면 RepeatStatus.FINISHED 로 반환해도 되는 지 궁금하다. 또한 외부API를 호출 할 때 PageNo도 명시를해줘야하는데 pageNo을 1씩 증가시키다가 특정 pageNo일때 오류가나면 해당 pageNo일때 부터 동작하도록 하려면 Jenkins의 매개변수 값을 설정해서 다시 batch를 돌리려고한다. 하지만 아래처럼 PAGE_NO을 정수로하고싶었는데 String으로 해야한다는 점이있어, 리스너에서 해당 매개변수를 Integer 또는 Long 타입으로 변경을 해야하는 과정을 추가해야 할 지 아니면 더 수월한 방법이 있는 지 궁금하다. 💀 [시스템 인텔리전스] 일반적으로 Tasklet에서 DB 트랜잭션 관리가 필요한 않은 경우가 많지는 않다. 모든 Tasklet이 데이터베이스 작업을 포함하는 것은 아니기 때문이다. 예를 들어, 파일을 정리하거나, 외부 API를 호출하거나, 단순한 알림을 보내는 작업이라면 DB트랜잭션을 고려할 필요가 없다. 그러므로 반복이 필요할 경우 작업의 성격을 잘 판단해서 while문으로 처리할지, RepeatStatus로 처리할지 현명하게 선택하라. 모든 반복을 RepeatStatus로 처리하는 것이 능사는 아니다.