학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요! 매번 좋은 강의 감사드립니다! 영속성 컨텍스트는 메모리 구조인데, 캐시와 버퍼 역할을 모두 한다고 이해해도 될까요? 캐시 는 자주 사용하는 데이터에 빠르게 접근할 수 있는 속도 향상이 목적이고, 버퍼 는 입출력을 잠깐 모아두는 임시 저장소 개념입니다. 영속성 컨텍스트가 둘 다의 역할을 한다고 볼 수 있을까요?
위 그림은 교재 195페이지 내용입니다. localhost:8080으로는 교재의 내용대로 잘 실행이 되었습니다. 그래서, 지금은 aws beanstalk에서(localhost:8080이 아니 aws 서버)에서 윗 부분을 실행 시켜볼려고 하니, 3가지에 부딪혔는데... 당장 내 서버(aws서버)의 upload폴더는 어디에서 볼 수 있으며, 어떻게 upload 폴더에 aaa.jpg를 올리며, 'localhost:8080/api/products/view/aaa.jpg 대신에 "beanstalk도메인/api/products/view/내파일이름"으로 위의 사진 처럼 실행시킬 수 있는지 위 3가지에 대해서 정중히 질문드립니다. (수정 추가) 지금 aws RDS 의 CRUD는 원활히 이루어지고 있습니다.
안녕하세요. 강의를 듣다가 QTodo 사용하는 시점에서 문제가 발생하여 문의드립니다. gradle 빌드시점에 QTodo 클래스를 생성하는 것 까진 확인을 하였는데 search1 메소드에서 QTodo를 사용하려고 하니 클래스 인식 자체를 못하고 있습니다.(import도 안됨) 강의 내용상으로 봤을 때 build 디렉토리에서 인위적으로 복사한 것 같진 않은데 해당 클래스를 어떻게 import해서 사용해야 할지 몰라서 문의드립니다. springboot 버전은 3.3.10입니다.
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 영한님 안녕하세요! 비슷한 질문이 있긴했는데.. AI 인턴 및 다른 답변들과 영한님이 이전 질문글 에서 남겨주신 부분이랑 조금 맞지 않는 부분이 있는 것 같아서 한 번 더 여쭤봅니다.. application.yml에서 설정하는 spring.jpa.properties .hibernate.jdbc.batch_size 속성 값과 쓰기지연저장소의 DB 쿼리 요청 방식이 조금 헷갈리는데요..! 쓰기지연저장소의 경우, 트랜잭션 커밋 시까지 SQL 을 모아두었다가, 트랜잭션이 커밋되는 시점에 flush()를 통해 DB에 쿼리를 하는 개념으로 알고 있습니다. 그러면 쿼리가 4개가 쓰기 지연저장소 버퍼에 있다고 할 때, 네트워크 전송은 1번만 이루어지나요? 아니면 4번 이루어지고, 네트워크 전송에서 이점을 얻는게 아닌, 커넥션을 맺는 행위를 1번만 함으로써 성능상 이점을 챙기는 걸까요? spring.jpa.properties .hibernate.jdbc.batch_size의 경우는, 한 번의 네트워크 전송마다 해당 size의 값만큼 쿼리를 보냄으로써, 네트워크 전송 횟수를 줄이는 데 그 목적이 있는 것으로 아는데, 쓰기 지연 저장소가 네트워크 전송을 커밋 시점에 1번으로 줄인다면 굳이 batch_size라는 속성이 필요한가 싶습니다..! 각각의 경우에 네트워크 전송이 어떻게 이루어지는 지 알 수 있을까요?
안녕하세요 선생님 강의 잘들었습니다.! 강의 이후 복습 하며 사이드 프로젝트를 하며 성장 하고 있습니다. 프로젝트를 하던중 궁금증이 생겨서 블로그 글을 찾아 보았지만 관련된 글을 찾지 못하여 질문을 드립니다. 회원 관련된 API = UserController -> UserService의 흐름으로 사용 하였습니다. 하지만 User API가 너무 많아져 특정 API를 수정할 때 찾기 어려워졌습니다. 그레서 이걸 분리 할수 없을까에 대한 고민이 생겼고 행위에 따라 분리 했습니다. [ Controller 분리 ] 검증 관련한 API를 VerficationController으로 모았습니다. VerficationController에서 필요한 자원에 따라 UserService, EventService를 사용 하였습니다. [ 질문 ] 1. Controller를 행위에 따라 부분적으로 분리 하여도 괜찮나요? UserController / EventController / VerificationController 분리 했을때 통일성이 없다는 느낌이 들어서 고민 입니다. Controller / Service 책임을 어떻게 설정 하시나요? 회원 관련된 요청이면 UserController 회원 로직이면 UserService를 사용 했습니다. 하지만 API가 너무 많아 분리를 할때 어떤 기준으로 분리를 해야 할지 모르겠습니다.
안녕하세요. 강의와 강의 자료를 보는 도중, 강의 자료에 있는 고아객체 - 주의 부분에서, @OneToOne, @OneToMany만 가능한 이유 에 대해서는 특별히 설명을 안해주신거 같아서요.. 혹시 @OneToOne, @OneToMany만 가능한 이유가 무엇인지 알 수 있을까요? 감사합니다.
src/main/resources/application.properties ``` groovy spring.profiles.active=local spring.datasource.url=jdbc:h2:tcp://localhost/~/test spring.datasource.username = sa ``` 이렇게 설정만 하면 스프링 부트가 해당 설정을 사용해서 커넥션 풀과 DataSource , 트랜잭션 매니저를 스프링 빈으로 자동 등록한다. (앞에서 학습한 스프링 부트의 자동 리소스 등록 내용을 떠올려보자.) 이 부분에서 자동 리로스 등록내용이 어디 강의에 있나요..?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] Requires_new를 통해 내부 트랜잭션이 시작되고 내부 트랜잭션은 커밋, 외부 트랜잭션은 롤백이라고 했을 때 그대로 동작한다고 이해하면 될까요?
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 우빈님! 테스트 강의 복습 중인데, 다시 들으니깐 너무 재밌네요... 다름 아니라, CQRS 에 따라서 강의를 진행하면서도 Controller와 Service를 CQRS에 따라 분리하고 있습니다. (패키지가 많아지긴하네요..ㅎㅎ..) 그런데 궁금한 부분은 Repsitory쪽인데, JpaRepository를 상속받는 인터페이스들(강의로 예를 들면 ProductRepository, StockRepository, OrderRepository가 있겠네요) 같은 경우인데, sprind data jpa 인터페이스에 CRUD 중에 CD 에 대한 책임을 줄 수는 있겠다 생각했고, U 는 변경감지에 책임을 맡기면 되겠다고 생각했습니다.. 그런데, 쿼리메서드 부분이 모호한데요. 작성했던 쿼리 메서드 같은 경우는 Query에 대한 부분인데 책임을 분리하려고보니, command에 query가 묶여있는 형태더라고요.. 이 부분은 어떻게 나누는지가 궁금합니다.. 제 짧은 지식 선에서는 QueryDSL 로 나눠야 하나 싶지만, 쿼리 메서드라는 편리한 것이 있는데 굳이 돌아가는 것 같다는 느낌이 드네요 제가 굳이 나누려는건지 싶기도 하구요... 조언을 구해봅니다..
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 안녕하십니까 선생님, 영속성 컨텍스트의 변경 감지에서 질문있습니다. 강의 내용 중 엔티티 클래스에는 가급적 Setter를 사용하지 말라고 하셨는데(특히 실무에서) 변경 감지라는 게 엔티티를 조회하여 영속성 컨텍스트에 저장을 해야 이 영속성 컨텍스트의 스냅샷을 통해 엔티티 필드의 값에 변경이 일어났을 때 update를 시키는 것이고 결국 엔티티의 필드를 수정 해야 하는데 그럼 필드를 수정하기 위해선 또 결국 Setter를 사용할 수밖에 없는 것 아닌가요???
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. UsernameOnly 인터페이스 타입과 지네릭스 타입으로 결과는 문제 없이 동작하지만 UsernameOnlyDto 타입으로 결과 값을 받으려고 findProjectionsByUsername를 호출하면 type mismatch 오류가 생깁니다. Specified result type [study.datajpa.dto.UsernameOnlyDto] did not match Query selection type [study.datajpa.entity.Member] - multiple selections: use Tuple or array List<UsernameOnlyDto> result = memberRepository.findProjectionsByUsername("m1"); package study.datajpa.dto; public class UsernameOnlyDto { private final String username; public UsernameOnlyDto(String username) { this.username = username; } public String getUsername() { return username; } } // List<UsernameOnly> findProjectionsByUsername(@Param("username") String username); List<UsernameOnlyDto> findProjectionsByUsername(@Param("username") String username); <T> List<T> findProjectionsByUsername(@Param("username") String username, Class<T> type); org.springframework.orm.jpa.JpaSystemException: Specified result type [study.datajpa.dto.UsernameOnlyDto] did not match Query selection type [study.datajpa.entity.Member] - multiple selections: use Tuple or array at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:341) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:241) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) at org.springframework.dao.support .ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) at org.springframework.dao.support .DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343) at org.springframework.dao.support .PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.data.jpa.repository.support .CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:136) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) at jdk.proxy2/jdk.proxy2.$Proxy149.findProjectionsByUsername(Unknown Source) at study.datajpa.repository.MemberRepositoryTest.projections(MemberRepositoryTest.java:403) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Suppressed: org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only at org.springframework.transaction.support .AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804) at org.springframework.transaction.support .AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:758) at org.springframework.test.context.transaction.TransactionContext.endTransaction(TransactionContext.java:135) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:272) at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:488) at org.springframework.test.context.junit.jupiter.SpringExtension.afterEach(SpringExtension.java:275) ... 2 more Caused by: org.hibernate.query.QueryTypeMismatchException: Specified result type [study.datajpa.dto.UsernameOnlyDto] did not match Query selection type [study.datajpa.entity.Member] - multiple selections: use Tuple or array at org.hibernate.query.sqm.internal.SqmUtil.throwQueryTypeMismatchException(SqmUtil.java:1272) at org.hibernate.query.sqm.internal.SqmUtil.verifyResultType(SqmUtil.java:1209) at org.hibernate.query.sqm.internal.SqmUtil.verifySelectionType(SqmUtil.java:1159) at org.hibernate.query.sqm.internal.SqmUtil.verifySingularSelectionType(SqmUtil.java:1114) at org.hibernate.query.sqm.internal.SqmUtil.checkQueryReturnType(SqmUtil.java:1088) at org.hibernate.query.sqm.internal.SqmUtil.checkQueryReturnType(SqmUtil.java:1049) at org.hibernate.query.sqm.internal.SqmUtil.validateQueryReturnType(SqmUtil.java:1040) at org.hibernate.query.sqm.tree.select .SqmSelectStatement.validateResultType(SqmSelectStatement.java:153) at org.hibernate.query.sqm.internal.QuerySqmImpl.<init>(QuerySqmImpl.java:240) at org.hibernate.internal.AbstractSharedSessionContract.createCriteriaQuery(AbstractSharedSessionContract.java:1483) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:1443) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:143) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:320) at jdk.proxy2/jdk.proxy2.$Proxy136.createQuery(Unknown Source)
트랜잭션 전파 활용까지 강의를 수강하고나니 이전 질문 해당 질문에서 질문했던 1번 경우에 대해서는 제 생각이 맞는 것 같다는 결론이 나왔습니다. 그리고 활용 강의까지 들으면서 느낀건데 애초에 UnexpectRollbackException 예외는 실제 정상 운영중인 서비스에서는 발생하면 안되는 예외고 테스트 과정같은 개발 환경에서 개발자가 캐치해서 이 예외가 발생하지 않게끔 코드를 수정하기위한 일종의 알림같은 예외라고 생각이 되었습니다. 그래서 굳이 exceptionhandler로 UnexpectRollbackException 예외를 처리하는것은 뭔가 옳지 않은 방법이지 않을까 하는 생각이 들었습니다. 제 생각이 맞나요?
만약에 @Transactional 어노테이션을 사용해서 트랜잭션을 만들었을때 내부 트랜잭션에서 롤백이 발생했다는건 일반적인 상황에서는 database에서 뭔가 예외가 발생해서 그런거라고 생각되는데, 그러면 예외처리기에서 알아서 runtimeException을 상속받은 예외로 바뀔것이고 외부 트랜잭션에서도 롤백이 발생한다는건 이 경우는 database에서 발생했던 예외가 외부 트랜잭션까지 넘어와서 자연스럽게 롤백된거라고 생각합니다. 그래서 UnexpectRollbackException이 발생하지 않는다고 생각됩니다. 제 생각이 맞나요? 그러면 UnexpectRollbackException 이 발생할 수 있는 경우는 뭐가 있나요? 강의에서 처럼 의도적으로 문제를 일으키는게 아니면 생각나는 경우가 딱히 없습니다. 하지만 제가 생각하지 못하는 것이지 예외가 발생한다는 경우가 있긴 있다는것이겠죠? 그렇다면 트랜잭션을 이용하는 순간부터는 그냥 @ControllerAdvice 에서 @ExceptionHandler로 UnexpectRollbackException을 캐치해줘서 처리하는 코드를 거의 무조건 작성해야할까요??