묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Formatter 구현 및 사용 이유 질문..
Formatter를 다른 구현체들을 사용하는게 아니라 직접 구현해서 사용하잖아요?그런데 이것에 대해서 궁금한게 있습니다..순전히 parse() 와 print() 를 저희가 직접 구현하는데.. 이 둘에 다른 특별한 기능이 있는 것도 아닌 것 같은데..저희가 Fommater를 implement하지 않고 그냥 하나의 인터페이스를 만들어 parse()와 print()를 직접 구현하는 것이랑은 무엇이 다른가요..? 저는 값만 넣으면 1000이 1,000이 된다거나 1,000이 1000이 되는 것을 생각했었는데 이 변환하는 것까지 직접 구현하는 것(물론 자바에서 지원하는 기능을 사용하기는 합니다)을 보고 위같은 의문ㅇ이 들었습니다.. 감사합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
IpPortToStringConverter이 호출되는 이유
11:40부터 시작하는 form을 제출했을때 호출되는 컨버터에 대한 질문입니다. 강의에서 제출 버튼 눌렀을때 127.0.0.1:8080라는 문자가 컨트롤러에 넘어간다고 하십니다. 해당 컨트롤러에는 @ModelAttribute가 있고 Form 을 변환하려고 했더니 IpPort객체가 있어서 문자를 IpPort객체로 변환해야하는데 이때 IpPortToStringConverter 이 또 호출된다고 하시는데요.여기서 왜 IpPortToStringConverter이 호출되는건가요? 문자에서 IpPort 객체로 변환해야하는 것이니까 StringToIpPortConverter가 호출되어야하는 것 아닌가요?
-
해결됨스프링 핵심 원리 - 기본편
discountPolicy 클래스에 대해서 질문
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]할인 정책에 클래스 에 대해서 궁금증이 생겨서 질문을 드립니다.동영상에서 영한님은 인터페이스를 통해서 fix, rate를 통해서 할인율을 분리 하는 것을 알 수 있었습니다.여기서 질문이 생깁니다.전에 중급1편에서 enum을(회원 등급을 만들 때 이넘이 생각나서 pdf를 찾아 보았습니다.)배울 때 할인율 넣은 게 있더라고요.(pdf 파일이 최신 버전이 아닐 수 있음)이넘에 할인율 을 넣기, 아니면 인터페이스를 통해 할인율 넣는 거에 따라 코드가 많이 바뀔 것 같은데요.이런 경우 어떤 게 나은지 알려 주실 수 있으신가요?답변 부탁 드립니다. 수정1 : "이런 경우"가 2개가 있어서 한개 로 수정.
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
테스트 간헐적 실패에서 대해서 다루나요?
안녕하세요섹션5 코드 다듬기까지 들은 시점에서 테스트 코드를 여러번 실행했을때 간헐적으로 실패를 경험합니다혹시 해당 내용 수정하는 부분이 끝까지 들으면 나오나요아래 에러내용 삽입했습니다. Failed to resolve parameter [com.clean.splearn.application.provided.MemberFinder memberFinder] in constructor [com.clean.splearn.application.provided.MemberFinderTest(com.clean.splearn.application.provided.MemberFinder,com.clean.splearn.application.provided.MemberRegister,jakarta.persistence.EntityManager)]: Failed to load ApplicationContext for [WebMergedContextConfiguration@350ec690 testClass = com.clean.splearn.application.provided.MemberFinderTest, locations = [], classes = [com.clean.splearn.SplearnApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OnFailureConditionReportContextCustomizerFactory$OnFailureConditionReportContextCustomizer@476fe690, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@6dd1c3ed, [ImportsContextCustomizer@49cb1baf key = [com.clean.splearn.SplearnTestConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7fdab70c, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@a451491, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@2aff9dff, org.springframework.boot.test.web.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory$DisableReactorResourceFactoryGlobalResourcesContextCustomizerCustomizer@15639440, org.springframework.test.context.support.DynamicPropertiesContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@cbfbc3c], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [com.clean.splearn.application.provided.MemberFinder memberFinder] in constructor [com.clean.splearn.application.provided.MemberFinderTest(com.clean.splearn.application.provided.MemberFinder,com.clean.splearn.application.provided.MemberRegister,jakarta.persistence.EntityManager)]: Failed to load ApplicationContext for [WebMergedContextConfiguration@350ec690 testClass = com.clean.splearn.application.provided.MemberFinderTest, locations = [], classes = [com.clean.splearn.SplearnApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OnFailureConditionReportContextCustomizerFactory$OnFailureConditionReportContextCustomizer@476fe690, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@6dd1c3ed, [ImportsContextCustomizer@49cb1baf key = [com.clean.splearn.SplearnTestConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7fdab70c, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@a451491, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@2aff9dff, org.springframework.boot.test.web.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory$DisableReactorResourceFactoryGlobalResourcesContextCustomizerCustomizer@15639440, org.springframework.test.context.support.DynamicPropertiesContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@cbfbc3c], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at java.base/java.util.Optional.orElseGet(Optional.java:364) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) Caused by: java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@350ec690 testClass = com.clean.splearn.application.provided.MemberFinderTest, locations = [], classes = [com.clean.splearn.SplearnApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OnFailureConditionReportContextCustomizerFactory$OnFailureConditionReportContextCustomizer@476fe690, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@6dd1c3ed, [ImportsContextCustomizer@49cb1baf key = [com.clean.splearn.SplearnTestConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7fdab70c, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@a451491, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@2aff9dff, org.springframework.boot.test.web.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory$DisableReactorResourceFactoryGlobalResourcesContextCustomizerCustomizer@15639440, org.springframework.test.context.support.DynamicPropertiesContextCustomizer@0, org.springframework.boot.test.context.SpringBootTestAnnotation@cbfbc3c], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130) at org.springframework.test.context.junit.jupiter.SpringExtension.getApplicationContext(SpringExtension.java:351) at org.springframework.test.context.junit.jupiter.SpringExtension.resolveParameter(SpringExtension.java:337) ... 3 more
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
JPA Entity Class 와 Domain Model Entity Class 를 분리해야 하는가? 에 대한 추가 질문
안녕하세요. 토비님!먼저 제가 정말 오랜 기간 고민해온 주제에 대해서 이렇게 강의를 내주셔서 너무 감사드립니다!!특히 강의에서 여러 차례에 걸쳐서 깊게 다룬, "JPA Entity Class 와 Domain Model Entity Class 를 분리해야 하는가?" 에 대한 토비님의 의견이 너무 공감되고 유익했습니다! 감사합니다!그리고 이에 대해서 두 가지 질문이 있습니다.첫 번째는,저는 사실 지난 3년 간 스타트업에서 Domain Entity 와 JPA Entity 를 분리해서 사용해왔습니다.그런데 강의에서 다뤄주신 내용이 제가 겪으며 갖게 된 생각과는 결이 조금 다르다고 느껴서 이렇게 질문을 드리게 되었습니다.제가 느꼈던 "Domain Entity 와 JPA Entity 를 분리해서 사용했을 때의 장단점"은 이랬습니다.장점 1. 도메인 모델의 수정이 DB 데이터 마이그레이션을 꼭 강제하는 게 아니라서, 도메인 모델 수정이 매우 자유롭습니다.상황에 따라 의도적으로 JPA Entity 클래스와 도메인 모델 클래스를 다른 모양으로 만들어두고 유지할 수 있습니다.(ex. User, UserDetail 이 쪼개져 있었는데, 어떠한 의사결정으로 인해 User 하나로 합쳐서 관리하는게 맞다는 판단이 든 경우, UserEntity, UserDetailEntity 는 놔둔 채로 User 만 합치는 게 가능.)장점 2. 도메인 모델들을 완전히 정규화된 구조로 가져갈 수 있습니다. 회사에서 비즈니스가 발전하다보면 종종 어쩔 수 없이 테이블에 성능을 위한 반정규화 필드나 soft delete 용 deleted_at 필드 등을 넣게 됩니다. 하지만 사실 이런 필드들은 순수 비즈니스 로직을 기술하는데에는 방해가 될 뿐인, 너무 Technical 한 부분들입니다. 이러한 반정규화 or 기능 필드들을 도메인 모델에는 넣지 않고 JPA Entity 에만 넣어서 어댑터에서 처리하면, 도메인 모델 내에서는 항상 순수 비즈니스 로직만을 기술할 수 있게됩니다.단점 1. JPA 의 lazy loading 을 활용할 수 없습니다. 항상 도메인 모델 객체는 완전한 상태로만 존재합니다. 그래서 성능 문제로 CQRS 패턴이 강제됩니다. 특히 저는 GraphQL 을 사용중이라 더욱 더 CQRS 가 필요했습니다.단점 2. Repository 의 save(= upsert) 로직을 직접 구현해야 합니다. 특히 복잡한 비즈니스의 핵심 도메인 모델들은 관계된 테이블도 많아가지고 이 save 구현이 엄청나게 길어집니다. 저는 이 save 로직을 직접 구현하고 관리할 때 회의감이 가장 많이 들었습니다. Spring Data JPA 가 그 동안 얼마나 압도적인 생산성을 제공해주고 있었는지도 느끼게 됐습니다.저는 스타트업에서 일하고 있다보니 특히 생산성을 중요하게 생각합니다.그런 점에서도 위의 장점들과 단점들이 모두 너무 치명적으로 느껴졌습니다.그래서 이 관점들에 대한 토비님의 의견과 토비님이 제 상황이시라면 어떤 선택을 하셨을지가 너무너무 궁금합니다. (참고로 저는 Kotlin Springboot + Spring Data JPA + Kotlin JDSL + GraphQL-Kotlin(code first)을 사용하고 있습니다.)두 번째는,사실 저는 Kotlin Springboot 를 사용중인데, 코틀린 언어와 JPA 가 너무 안 어울린다는 생각을 종종 합니다.예를 들면, DB table 에 정의된 column default 값을 쓰려면 JPA Entity 의 해당 필드에 null 을 넣어서 보내야하는데, 보통 테이블 컬럼에 default 를 쓰는 경우는 대부분 해당 컬럼이 not null 타입입니다. 그래서 당연히 JPA Entity 에도 필드 타입은 not null 로 하고 싶어집니다.물론 @Column(insertable=false)를 사용하긴 하지만, 결국 그럼 이 JPA Entity 객체를 생성할 때 해당 필드에 실제로 저장되지도 않을 값을 거짓으로 넣어야 하는 상황이 생깁니다.그래서 조금 더 Kotlin 에 잘 맞는 Exposed 를 고려하자니, 도메인 모델 클래스와 JPA Entity 클래스 분리가 강제되는 느낌이고, 이게 과연 JPA 의 생산성을 따라올 수 있을까? 올바른 선택이 맞을까? 하는 의문이 듭니다.그래서 궁금한 점은,혹시 토비님이 추천하시는 좀 더 Kotlin 언어에 잘 맞고 Kotlin Springboot 를 생산적으로 사용할 수 있는 방법이 있을까요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
user-loanHistory 폴더 구조 질문
안녕하세요!@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<UserLoanHistory> userLoanHistories = new ArrayList<>(); 이 코드를 봤을 때 User와 UserLoanHistory는 강한 연결관계를 가지고 있는 것 같습니다(이를 같은 aggregate라고 하는 것 맞나요?). 그래서 폴더 구조를 user 밑에 loanHistory를 넣으신 것 같은데, 일반적으로 이런식으로 폴더 구조를 잡나요? 아니면 domain 폴더 아래에 user와 같은 레벨로 loanHistory를 만들고, 대출 기능도 BookService에서 구현하는 게 아니라 UserLoanHistory용 컨트롤러/서비스/레포지토리를 따로 만들어 구현해도 되나요?
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
동일 계층의 애플리케이션 서비스가 서로의 인터페이스를 사용하여 의존하는 경우에 대해서
안녕하세요? 존경하는 토비님 작은 질문하나 드리겠습니다. 회원 애플리케이션 기능 추가의 25:00~26:00 에서는 MemberFinder 인터페이스를 정의하고 기존 MemberService에 혼재된 멤버 조회로직을 CQRS에 따라 구현클래스를 분리했습니다. 그리고 이를 MemberModifyService에서 사용하고 있습니다.말씀 주신 것처럼 단순히 조회이고 변경이 없다는 가정하에 이처럼 인터페이스를 정의하고 이를 통해 사용을 하는 것은 잘 이해가 됩니다!다만 저는 같은 계층에서 있는 서비스 빈이 서로를 의존하지 않는 방향으로 개발을 해오고 있었는데요. 그래서 토비님의 방식에 대해 공부하면서 같은 계층에서 인터페이스 포트를 통해서 호출하는 것은 괜찮을까 고민이 들었습니다.만약 그게 설계적으로도 문제가 없다면 앞으로도 토비님의 방식으로 개발하고 싶은데요. 분명 토비님께서 오랫동안 고민하신 개발 원칙/기준이 있을 것 같아서 여쭤봅니다.같은 계층에 있는 애플리케이션 서비스 빈이 서로를 의존, 또는 인터페이스를 통해 사용되는 경우 지켜야할 기준이나 원칙이 있을까요?*추신저는 토스의 김재님의 [블로그](https://geminikims.medium.com/%EC%A7%80%EC%86%8D-%EC%84%B1%EC%9E%A5-%EA%B0%80%EB%8A%A5%ED%95%9C-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EA%B0%80%EB%8A%94-%EB%B0%A9%EB%B2%95-97844c5dab63)를 접해서 위와 같이 개발해오고 있었습니다. 저는 계층을 하나 두고 유틸성 빈을 만들고 이를 사용하게끔 했습니다.(블로그내용 아래 일부 발췌) > 네 번째 규칙동일 레이어 간에는 서로 참조하지 않아야 한다.(다만, Implement Layer는 예외적으로 서로 참조가 가능합니다.)
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
OSIV ON 상태일 때
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. 항상 강의 잘 듣고 있는 학생입니다. 다름이 아니라 강의자료에 "OSIV ON 사진"을 보시면 Filter Interceptor, View, Controller는 영속 상태임에도 불구하고 수정 불가능이라고 적혀 있습니다. 제가 지금까지 알고 있는 바로는 영속성 컨텍스트가 존재한다는 것은 데이터베이스 커넥션을 갖고 있다는 뜻이라 위 3개의 파트에서 데이터 수정이 발생하면 Flush를 통해 데이터 수정이 가능한거 아닌가요 ?혹시 제가 사진의 내용을 잘 못 이해한건지 아니면 위 내용을 잘 못 이해한건지 궁금해서 질문 드립니다. 감사합니다. 무더위 조심하세요 !
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
지금들어도될지
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]혹시 나온지가 좀 된 강의인데 지금들어도 버젼이라든지 상관없을까요?
-
미해결실전! 스프링 데이터 JPA
bulk insert 질문입니다.
안녕하세요.bulk insert 관련해서 궁금한점이 있습니다.사실상 데이터베이스를 다룰 때 IDENTITY를 거의 사용할 것이라고 생각합니다.이럴 경우 bulk insert를 어떻게 처리해야 될 지 궁금합니다.다른 질문에 답변을 봤을때 책에 나온 쓰기 지연같은 경우도 IDENTITY에서는 안되는 것이라고 알고 새로운 질문을 드립니다.IDENTITY 키를 가진 엔티티들 bulk insert를 하기 위해 JdbcTemplate가 최선이다 까지 이해했습니다. 예를 들어 상품을 등록할때 상품과 카테고리들 이미지들을 저장한다고 생각해보겠습니다.(각각 다른 테이블 및 1:N)이런 경우 상품에 새로운 엔티티들을 만들고 save를 호출할 경우 IDENTITY를 가진 엔티티들이니 각 쿼리들이 따로 다 날라갑니다.그래서 JdbcTemplate를 사용해 카테고리들과 이미지들을 batch insert할 경우기존 엔티티에 정보를 어떻게 관리하는지 궁금합니다. jdbcTemplate로 bulk insert한 경우 id를 받아오지 못하는 것으로 알고 있는데, 이런 경우 jdbcTemplate으로 값을 넣은 후에 기존 상품 엔티티에서 카테고리 혹은 이미지들에 접근할 경우 lazy 기능이 동작하지 않을 것이라 생각되는데 실무에서는 bulkInsert하는 경우 lazy하는 값에 접근하지 않는다. 이런 약속을 정해놓고 개발하시는건가요?아니면 batchInsert로 넣는 값들은 내부에서 가지고 있지 않고 추후에 조회할때 조인도 사용하지 않으시나요? 질문 의도는 결국 IDENTITY인 경우 batch insert를 어떻게 해야 좋은 것이고, 만약 jpa에서 처리가 안될 경우(JdbcTemplate 등을 사용) 영속성 컨텍스트와 어떻게 문제가 생기지 않고 처리하시는지 궁금해 질문드렸습니다.제 짧은 생각으로는 어떻게든 영속성 컨텍스트 문제가 생길 것 같은데, 실무에서는 그럼 이런 엔티티는 드무니까 save 코드 주석으로 특정 lazy 값에는 접근하지 말라는 내용을 써놓고 컨벤션 느낌으로 개발하시는지도 궁금합니다.jpa, data jpa와 querydsl 강의를 모두 수강하였기 때문에 jpa에서만 국한되어 답변해주시지 않고 data jpa, querydsl, JdbcTemplate 혹은 다른 방법 어떤 내용을 포함해주셔도 공부하고 이해할 수 있습니다. 항상 좋은 강의 감사드립니다.
-
미해결실전! 스프링 데이터 JPA
교만했던 것 같아요.
항상 만족합니다.
-
미해결실전! 스프링 부트와 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만건 모두 조회되는 것 아닌가요?이럴 때도 메모리에 대한 문제가 있을 것 같은데 제가 잘못 이해한 것인지 설명 부탁드리겠습니다!
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
그라파나 대시보드 오타가 있는 거 같아요
그대로 복붙 해봤는데 p95가 두개있어서 p50를 측정 안하고 있었슴미다그래서 json 살펴보니 [0.95]"expr": "max by(http_method, path, query_type) (app_query_per_request{quantile=\"0.95\"})", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false,"legendFormat": "P95 - {{http_method}} {{path}} - {{query_type}}", [0.50]"expr": "max by(http_method, path, query_type) (app_query_per_request{quantile=\"0.95\"})","hide": false, "instant": false,"legendFormat": "P50 - {{http_method}} {{path}} - {{query_type}}", 아래 0.50에 0.95의 값을 대입하고 있떠라구요잘 작성된 건가요 오타인건가요
-
해결됨토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
도메인 로직에 대해서 궁금한 것이 있습니다.
현재 Member 도메인 모델 확장 까지의 수업을 듣고 궁금한 것이 있습니다! 저희가 이번 수업을 포함하여 지금까지 요구사항(도메인) -> 도메인 모델(회원) -> 비밀번호 해시라는 일련의 과정을 통해 비밀번호 암호화와 관련한 도메인 모델의 규칙, 속성, 행위 등을 뽑아냈기 때문에 비밀번호 암호화까지 도메인 로직에 포함된다고 이해했습니다. <인터페이스 위치를 결정하는 기준에 대해> 해당 답변에서도 PasswordEncoder를 어디에 둘지 결정할 때 사용한 기준은 도메인 모델을 이야기할 때 이게 등장하는가 라고 말씀해주시기도 했고요! 그렇다면 개발은 결국 요구사항을 토대로 진행되는 것이기에 모든 코드가 도메인 로직으로 분류되어야 하는 것 아닌가? 하는 의문점이 생겼습니다! 토비의 생각을 듣고 싶습니다!
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
HttpSecurity.authorizeHttpRequests() - 2 강의 부분에 대한 질문
현재 제 build.gradle은plugins { id 'java' id 'org.springframework.boot' version '3.5.0' id 'io.spring.dependency-management' version '1.1.7' } group = 'io.security' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() } 같이 설정이 되어 있습니다. AntPathRequestMatcher, MvcRequestMatcher가 사용이 되지 않는다고 자동완성때 밑줄이 쳐져 있어서.requestMatchers("/manager/**").hasAuthority("ROLE_MANAGER") .requestMatchers("/admin/payment").hasAuthority("ROLE_ADMIN")이렇게 수정하였는데 맞게 수정 한 것인지 문의 드립니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
양방향 연관관계 알아보는 법?
안녕하세요. 8분쯤 양방향 연관관계 시 @JsonIgnore 어노테이션을 통해 순환 참조가 되는 것을 방지해야 한다고 알려주셨는데, 엔티티 하나하나 들어가서 직접 확인해야 하나요?ERD나 관계가 복잡해서 까먹을 경우 이렇게 하나씩 확인을 해야 하는지, 아니면 IDE 같은 걸로 도움을 받을 수 있는지 궁금합니다.
-
미해결실전! 스프링 부트와 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 이런식으로 가져가야 하는지 궁금합니다.아니면 다른 해결 방법이 있으시다면 알려주시면 감사하겠습니다.