묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
Exception 정의 기준
application 쪽에서는 커스텀 예외를 정의해서 사용했는데 Profile과 Email 레코드에서 값 형식 검증 부분에서는 표준 예외를 사용하셨더라구요 예외를 분리해서 사용하는 기준이 무엇일까요?
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
개인적질문
안녕하세요 토비님 가의 잘 보고 있습니다. DDD는 처음이고 헥사고날방식도 처음이라 질문 수준이 낮은 점 양해 부탁드립니다!이 강의까지 보고나서 전체코드를 봤을떄 궁금한 점들이 있어서 질문 드립니다!1번 질문:@Entitypublic class Member { @Embedded private Address homeAddress;} @Embeddable public class Address { private String city; private String street; private String zipcode;}@Embeded사용할때 데이터 필드를 의미 있는 하나의 묶음 이라는 의미로 사용하는데 profile 이나 email같은 경우에는 컬럼이 하나여도 @Embeded 로 묶으셨는데 그 기준(언제 사용해야하느지)가 궁금합니다. 저라면 그냥 생각 없이 String 으로 받았을거같은데 ….!2번 질문 : Aggregate root 로 접근해하면 메서드 체이닝 비슷하게 일어나는거 같은데 그런 점은 괜찮나요!?3번 질문 :. Aggreagate root로 접근하는 방식은 DDD에서만 사용하는지 ?? 기존 JPA + 레이어 아키텍쳐에서도 사용이 가능한건지....?4번 질문 : 강의에서는 1:1 이였지만 , ManyToOne 단방향 , ManyToOne OneToMany 양방향 관계에서도똑같이 Aggregate root로 접근해서 데이터를 처리해야하는지..?미리 감사드립니다!!
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
어플리케이션 , 도메인 계층질문
안녕하세요 토비님어플리케이션 계층의 port는 도메인과 외부의 연결을 위해 필요 하다고 알고 있는데jpa나 마이바티스 같은 기술 또한 도메인 외부의 내용이기에 인프라 계층으로 들어간다고 알고 있습니다그런데 의존성 역전을 위한 레파지토리 인터페이스를 어플리케이션 계층에 만들면 어플리케이션 서비스에서 도메인에 관련된 내용을 너무 깊게 관여하는 것 같아서 질문 드립니다어플리케이션과 도메인의 경계를 어디까지로 보는게 좋을까요
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
record class @Transactional 사용에 대해서
안녕하세요 토비님 회원 애플리케이션 서비스 테스트 (2) -25:19에 대해 질문 드립니다. record 에 @Transactional을 사용하면 실행에는 문제가 없으나 인텔리제이에서 Classes annotated with '@Transactional' could be implicitly subclassed and must not be final 이와같은 경고 메세지를 주는데 무시하고 지나가도 되는건지요?
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
39. 문서와 코드 다듬기 updateInfo 테스트 질문 있습니다.
토비님 안녕하세요. 39. 문서와 코드 다듬기 강의의 updateInfo 테스트 부분 질문이 있습니다. 강의 28:30 부근에서 updateInfoFail()에 코멘트를 달게 되는데 성공케이스에 대한 코드는 updateInfo() 부분으로 옮기는 것도 좋아보이는데 토비님 생각이 궁금합니다. updateInfoFail()의 마지막에 member가 member2의 프로필 주소와 중복되는 테스트가 있으므로, member2의 프로필 주소를 설정해주는 코드가 필요하지만, 하나만 있어도 괜찮지 않을까 생각합니다.그래서 나머지 성공에 대한 코드는 updateInfo() 메소드로 옮겨 "상세 정보 수정이 가능한 경우"들을 나열하는게 좋다고 생각했습니다. 똑같은 준비작업이 반복되다보니 한 번 세팅해놓고 여러 케이스를 다 검증해보는 것이 낫다고 하셨는데, 현재 테스트 클래스 메소드가 성공/실패로 나뉘어져있어 성공하는 부분은 다른 메소드로 이동하는게 좋아보인다 생각했습니다. 아래 코드에서 성공 케이스와 실패 케이스로 나누어보았습니다.코드updateInfo()@Test void updateInfo() { Member member = registerMember(); Long memberId = member.getId(); memberRegister.activate(memberId); entityManager.flush(); entityManager.clear(); var updateRequest = createMemberInfoUpdateRequest(); member = memberRegister.updateInfo(memberId, updateRequest); assertThat(member.getDetail().getProfile().address()).isEqualTo(updateRequest.profileAddress()); // 기존 프로필 주소로 계속 변경 요청 가능 memberRegister.updateInfo(memberId, updateRequest); // 다른 프로필 주소로 변경 가능 memberRegister.updateInfo(memberId, createMemberInfoUpdateRequest("omg123")); // 프로필 주소 제거 가능 memberRegister.updateInfo(memberId, createMemberInfoUpdateRequest("")); } updateInfoFail()@Test void updateInfoFail() { Member member = registerMember(); Long memberId = member.getId(); memberRegister.activate(memberId); member = memberRegister.updateInfo(memberId, createMemberInfoUpdateRequest()); Member anotherMember = registerMember("another@email.com"); Long anotherMemberId = anotherMember.getId(); memberRegister.activate(anotherMemberId); entityManager.flush(); entityManager.clear(); // anotherMember가 member와 프로필 주소 중복 MemberInfoUpdateRequest duplicateProfileUpdateRequest = createMemberInfoUpdateRequest(member.getDetail().getProfile().address()); assertThatThrownBy(() -> { memberRegister.updateInfo(anotherMemberId, duplicateProfileUpdateRequest); }).isInstanceOf(DuplicateProfileException.class); // member와 중복되지 않는 프로필 주소로는 변경 가능 MemberInfoUpdateRequest updateRequest = createMemberInfoUpdateRequest("profile123"); memberRegister.updateInfo(anotherMemberId, updateRequest); // member가 anotherMember와 프로필 주소 중복 assertThatThrownBy(() -> { memberRegister.updateInfo(memberId, updateRequest); }).isInstanceOf(DuplicateProfileException.class); } 좋은 강의 해주셔서 감사드립니다!
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
섹션 6 -2강
xml관련 설정강의자료로 남겨주신다고 했는데 어디서 찾을 수 있나요?
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
unique-constraint 설정 질문드립니다.
orm.xml unique-constraint 설정 부분 설명해주신 부분에서 인덱스로서 성능을 위해서, 데이터 중복저장 문제를 위해서 설정을하면 좋다고 말씀해주셨는데요<index unique="true">설정의 차이점이 뭔지 잘모르겠습니다
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
@ResponseBody 로 도메인 레이어의 MemberRegisterRequest 를 그대로 사용하는 것에 대해서
안녕하세요. 토비님, 강의 잘 듣고 있습니다. 🙂오늘은 강의 내용에서 좀 굉장히 의외인 부분을 발견해서 질문드립니다.강의 #41. MemberApi와 웹 단위 테스트 에서 MemberRegisterRequest 가 domain 레이어에서 정의했던 클래스임에도, @RequestBody 파라미터 그대로 쓰셨는데, 이 부분이 많이 의외고 우려가 되었습니다.저렇게 하면 MemberRegisterRequest 클래스의 코드 변경이 api 스펙 변경을 의미하는지가 코드리뷰 상에서 쉽게 보이지 않고 숨겨질 수 있다는 염려가 됩니다.실제로 MemberRegisterRequest 에 필드를 추가해서 PR 을 올리면 코드리뷰어가 봤을 때 domain 레이어의 특정 모델에 필드가 추가됐을 뿐인 작은 변경으로 보일 것입니다. 그래서 그것이 어느어느 API 의 스펙에 영향을 주는지 알기가 너무 어려울 것 같습니다.그래서 저는 API 의 스펙이 되는 Request, Response DTO 의 경우 반드시 클래스를 별도로 분리해야한다고 생각합니다.API 스펙은 server 마음대로 변경할 수 있는 서버만의 코드가 아니라 client 와의 계약 문서라고 보기 때문입니다.그래서 Request/Response 같이 백앤드 엔지니어가 함부로 변경할 수 없는 영역과 맘대로 변경 가능한 영역을 분리해서, 어플리케이션과 도메인 로직의 변화가 API 스펙 변경으로 인한 장애 걱정으로 이어지지 않게 하는 것이 중요하다고 생각합니다.이게 근데 단순히 클래스 분리만 해둬도 PR 에서 API 스펙이 어떻게 바뀌는지 쉽게 트래킹이 가능해지기 떄문에 이 부분 만큼은 번거롭더라도 실보다 득이 훨씬 많아서 꼭 분리해야한다고 생각해왔습니다.이 부분에 대해서 어떻게 생각하시는지 궁금합니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
안녕하세요 토비님!
안녕하세요 토비님! 강의를 보다가 궁금한 점이 생겨서 질문 드립니다. 테스트 코드 작성시 EmailSender같은 경우나 , 외부 요인(?) 같은 경우에 저는 테스트 코드가 외부요인에 의해 영향받기를 원하지 않아 @MockitoBean을 사용하는데요 그런데 강의에서는 왜 @MocktioBean을 사용하시지 않고 @TestConfiguration을 사용하셨는지 궁금합니다!감사합니다!
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
자신의 정보만 업데이트 하는 로직 궁금한 점
38강 10분 13초에서 자신의 정보를 업데이트 하는 로직 만드는 부분에서 궁금한 점이 생겼습니다.로그인된 사용자만 자기 정보를 업데이트 할 수 있는 기능을 웹 API 쪽의 어댑터에서 만든다고 하셨는데 왜 그런걸까요? 애플리케이션에서 검증을 하면 안되는걸까요?
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
디스코드 채널 입장이 안돼요!!
어떻게 들어가야되죠?!
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
Member를 activate 시 deactiavatedAt 초기화 필요성 질문입니다
Member activate 호출 시 MemberDetail의 activate 또한 호출 하게 되는데요.이때 MemberDetail의 activate 로직에서 this.deactivatedAt = null 을 통해 비활성 일시는 초기화 해주어야활성 -> 비활성 -> 활성 -> 비활성 시 deactivatedAt이 null임으로 문제가 없을 것 같은데 어떻게 생각하시나요?
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
MemberRegisterTest에서 @SpringBootTest 질문
MemberRegisterTest를 진행할 때 @SpringBootTest를 사용해서 테스트를 진행했는데요서비스 테스트에는 @ExtendWith(MockitoExtension.class)를 사용하는 경우를 많이 봤습니다 헥사고날 아키텍처에서는 애플리케이션과 도메인이 중심이 되기 때문에 서비스에서 @SpringBootTest를 사용한걸까요?
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
ApiControllerAdvice에서 2개 이상의 Exception 타입 핸들링
안녕하세요.ApiControllerAdvice에서 하나의 Handler 메서드에서 아래 2개 Exeception 타입을 처리하시도록 변경하셨는데요.- DuplicateEmailException- DuplicateProfileException 이렇게 할 경우, 아래와 같이 두 Exception의 공통 타입인 RuntimeException 객체로 파라미터를 받아야 하는거 아닐까요?@ExceptionHandler({DuplicateEmailException.class, DuplicateProfileException.class}) public ProblemDetail duplicateExceptionHandler(RuntimeException e) { return getProblemDetail(HttpStatus.CONFLICT, e); } 감사합니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
Member와 MemberDetail의 연관관계 주인이 바뀐게 아닌가 싶습니다.
안녕하세요.Member와 MemberDetail의 연관관계 주인이 바뀐게 아닌가 싶습니다.비록 1:1 관계이고, 두 객체 인스턴스가 동시에 생성되고 테이블에 영속화 되게끔 설정된 거는 맞지만,논리적으로 Member 엔터티가 상위 엔터티이고, MemberDetail이 하위 엔터티가 맞는 것 같아요.추후 Member 엔터티를 참조하는 다른 엔터티가 만들어질텐데,MemberDetail을 참조하는게 아니라 Member를 참조해야 하고요.관련한 의견 부탁 드립니다.감사합니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
DuplicateEmailException에 @ResponseStatus(HttpStatus.CONFLICT) 애너테이션 사용
안녕하세요.도메인 영역에 @Entity, @Query 애너테이션을 사용하는게 문제가 없다는 내용과 이유를 강의에서도, 질문&답변에서도 잘 설명해 주셨고, 모두 확인했습니다. 동일한 이유로,강의에서 DuplicateEmailException에 @ResponseStatus 애너테이션 사용 시, 의존성 문제에 대해서 언급한 부분도, JPA 애너테이션을 사용할 수 있다는 동일한 근거로 허용되어도 문제가 없는게 아닐까요?물론, @ResponseStatus 사용 시에 상태 코드 외에 추가적인 메시지 설정이 불가능하다는 등 단점이 있어서 사용하지는 않겠지만요. 그저 기술 의존성 침투 관점에서 궁금해서 문의 드립니다.감사합니다.
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
MemberRepository의 JPA 종속성에 관하여
쉽게 이해할 수 있게 설명해주셔서 강의 잘 봤습니다. 👍 강의 후반부(39. 문서와 코드 다듬기)에 MemberRepository에 @Query를 사용하면서 JPA 종속성이 추가되었는데 이 부분에 대해서 언급 없이 2가지 조인 방식과 관련하여 설명하고 넘어갔습니다.강의 중반부(23. 회원 애플리케이션의 포트 정의)의 MemberRepository 설명과 같이 spring-data-commons의 Repository라는 마커 인터페이스를 사용하는 것은 동의하나 application layer에 기술 종속성이 추가된 내용 관련하여 부가 설명 요청 드려도 될까요? 물론 다음 강의에 해당 설명이 있을것으로 생각되지만.. MemberQueryRepository로 분리하고 adapter layer에서 구현하는 방향이 더 좋아보이는데 개선 방향도 같이 부탁드립니다.
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
FK 제약조건 관련해서 자동 키생성 문제
해당 강의를 수강하고 하루죙일 찾아봤지만 실질적으로는 문제를 해결하지 못했습니다. ㅜㅜ 문제가 왜 발생했는지 추적한 결과실제로 xml를 불러들일때, fk 관련 속성을 잘 갖고 오지만,@JoinColumn 을 생성할 때 fk 속성을 삽입하는 코드가 실질적으로 존재하지 않고,fk제약 조건 생성을 위해 alter 시에@JoinColumns로 지정됩니다. 실제 어노테이션 기법으로 작성 할 경우 @JoinColumn으로 수집이 되지만,-참고-@JoinColumns 으로 수집 시xml 스펙에서 join-column 태그는 Unbounded로 스펙이 정해져 그렇게 처리 된 거 같아요. 하이버네이트 6.6 버전에서는 jpa 매핑 관련해서 xml 3.1 버전으로 관리되고, 7.0 버전부터는 xml 7버전으로 매핑이 관리될 것 같습니다. 하이버네이트 6.6 버전에선 실질적으로 버그라고 생각되고, 7.0 버전에는 JPAXMLOverridenAnnotationReader 클래스가 사라진 상황이라 7 버전으로 올려서 확인해봐야 할 것 같지만, 스프링 부트 3.x.x버전은 아무래도 하이버네이트 6.6 버전 기준으로 버저닝이 될 거 같아 해당 문제의 해결 방법은 실질적으로 찾진 못했습니다. ㅜ
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
MockMvcTester 에도 MockMvc의 doPrint()같은 메소드가 있나요
찾아보다가 잘 못찾겠어서 문의 드립니다 ㅜㅜ
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
그럼에도 결코 수긍하지 않는 사람들이 있으니 말이죠
토비님의 의견에 동의합니다.화면에서 필드 하나 필요하다는 수정사항을 처리하기 위해 Presentation 레이어 이외의 클래스들을 수정하고 싶진 않아요. 그럼에도 불구하고 현업에선 정말 수많은 이유를 들어서 DTO로 반환하는 걸 유지하려고 합니다. 별도의 관심사를 끌어안게 되면서 애플리케이션 레이어의 테스트 코드 작성이 까다로워지고, 그로 인해 안정성이 하나씩 무너지고 균열이 생기기 시작하는 지점이 이곳이지 않을까 싶어요. 어찌보면 강의를 들을까 고민하던 때에 가장 매력있게 보였던 챕터였고, 무언가 해답을 얻을 수 있을까 했지만 여전히 뭔가 용기가 생기진 않는 것 같습니다.물론 그것이 토비님 탓은 아니죠. 훌륭한 가르침이지만, 단지 이것을 제 현장에 전파할 때 발생할 어려움에 벌써 머리가 아파지는 것.. 그 뿐입니다. 질문은 아니고 그저 넋두리였습니다.나머지 강의 마저 잘 들어보겠습니다. 감사합니다