![Thumbnail](https://cdn.inflearn.com/public/courses/324214/course_cover/8ce5e6b5-6b31-4659-a0cd-eec20efc13f4/kyh_JPA_Spring2.png)
25%
66,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
dto에서의 join질문이있습니다.
좋은강의감사합니다. 질문이있습니다. 엔티티조회방식에선 fetch join을 했는데, 여기에선 왜 일반 join을 하는 것인가요??
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
준영속 상태 엔티티에 대해 질문드립니다.
안녕하세요 강사님! 우선 강의 매우 유익하게 잘 듣고 있습니다. 몇가지 궁금한 점이 있어 질문남깁니다. 1. 한번 영속 상태가 된적 있는 엔티티는 트랜잭션이 끝나면 준영속 상태가 된다고 하셨는데 이 준영속 상태가 된 엔티티가 저장되어 있는 위치가 2차 캐시가 맞나요? 2. 한번 영속상태에서 준영속 상태가 된 엔티티는 에플리케이션이 종료되기 전까지 계속 준영속 상태로 저장되는 건가요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
페이징을 위한 쿼리 질문드려요!
지난 번 사소한 질문에도 친철히 답변해주시고 알찬 강의 항상 감사드립니다! JPA 최적화 강의를 완강했습니다. 현재 간단한 프로젝트를 진행하고 있는데 페이징에 대해 질문드립니다. DB서버에 select한 데이터의 개수를 지정해서 가져오는 페이징 쿼리를 호출하는 이유로 ' application 메모리에 로드할 수 있는 데이터의 양은 제약이 있기 때문에 한 번의 쿼리로 너무 많은 데이터를 가져올 경우 시스템에 에러가 날 수 있다.' 이렇게 생각했습니다. 질문1) 그럼 시스템이 견딜 수 있는 메모리의 성능을 최대한 고려해서 한 번의 쿼리로 최대한 많은 데이터를 가져오고 최종적으로 모든 데이터를 가져오기 위해 날리는 쿼리의 개수를 최소화하는 게 최적화를 위한 올바른 이해인가요?? 질문2) 조금 다른 질문입니다! 만약에 회원가입 시 ID 입력에 대한 요구사항이 1. 100글자를 넘기지 않는다 2. 중복된 ID가 있어서는 안 된다 라고 했을 때 1번 요구사항을 프런트에서 처리했다면 백에서는 1번 요구사항에 대해서는 구현하지 않고 2번 요구사항만 검증하는 식으로 현업에서도 코드를 짜나요?? 항상 너무너무 감사합니다!
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
커맨드와 쿼리 분리
MemberService의 update 메서드에서 Member를 그대로 반환하지 않는 이유가 커맨드와 쿼리를 분리하기 위해서라고 하셨는데 정확히 이해가 가지 않습니다 ㅠ 1. Member를 update 메서드에서 그대로 반환하면 왜 영속상태가 끊킨 Member가 반환이 되나요? 2.Member를 그대로 반환하면 updateMemberV2 메서드에서 Member member = memberService.update(id, request.getName());return new UpdateMemberResponse(member.getId(), member.getName()); 이런식으로 되면 오히려 강의에서 수정한 Member를 찾는 Select 쿼리 안날라가서 커맨드와 쿼리를 분리할 필요가 없는게 아닌가요..? * 여담으로 스프링 MVC 강의 11월에 출시된다고해서 기다리고있었는데 12월로 미뤄졌네요ㅠㅠ 빨리 듣고싶어요~
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
안녕하세요!
안녕하세요 강사님 늘 좋은 강의 감사드립니다. 다름아니라 저는 비전공자인데 강사님 강의를 들으면서 따라하고 있는데 저도 프로젝트를 경험해보고 싶은데 어떤 방법이 있을지 알 수 있을까요 ... ? 너무 사소한 질문이지만 답변 부탁드립니다 ..
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
안녕하세요 질문드립니다.
안녕하세요. 영한님 덕분에 강의를 시청하고 jpa로 프로젝트를 진행하고있습니다. 현재 "User"객체, "Movie" 객체 그리고 "Score" 객체로 Movie <1 : N> Score <N : 1> User 이런식으로 유저가 영화에 부여한 평점에 대해 관계를 맺고있습니다. 이제 여기서 평점이 특정 점수 이상인 영화목록을 평점과 함께 가져오려고합니다 select movie0_.content_id as content_2_5_, movie0_1_.category as category3_5_, movie0_1_.description as descript4_5_, movie0_1_.dtype as dtype1_5_, movie0_1_.main_title as main_tit5_5_, movie0_1_.image_id as image_id7_5_, movie0_1_.production_date as producti6_5_, movie0_.book_rate as book_rat1_11_, movie0_.country_code as country_2_11_, movie0_.netflix_yn as netflix_3_11_, movie0_.watcha_yn as watcha_y4_11_, movie0_.origin_title as origin_t5_11_, movie0_.running_time as running_6_11_, movie0_.total_audience as total_au7_11_ from movie movie0_ inner join content movie0_1_ on movie0_.content_id=movie0_1_.content_id where ( select avg(score1_.score) from score score1_ where movie0_.content_id=score1_.content_id )>=4.0 limit ? 대충 이런 쿼리로 생각하고있습니다. 근데 점수(score)를 중간 테이블로 분리하다보니 이걸 dto에 맵핑하는 과정에 좀 고민되는 부분이 있습니다. Movie 엔티티에 averageScore라는 컬럼을 넣을순없으니 이걸 어떻게 해야하나 싶은데 1. jpql로 순수한 Movie엔티티를 먼저조회하고 그 정보를 가지고 영화들의 평균점수를 조회한뒤 합친다. 이렇게하면 영화조회할때 avg(score) 비교연산 하는부분의 서브쿼리를 평균점수 조회때 한번 더 돌려야합니다. 그리고 가져온뒤 pk값으로 맵핑을 일일이해줘야하는데 jpa가 해야할일을 제가하는 느낌입니다. 2. jpql로 애초에 DTO로 맵핑하게끔해서 한번의 조회로 끝낸다. 근데 뭔가 jpql에서 바로 DTO로 조회하는게 탐탁치않습니다. 3. 네이티브쿼리를 쓴다. 제일 간단한 방법인데 사실상 2번 방법이랑 비슷한거 같네요. 어떤게 가장 jpa스러운 해결방법인지, 사실 위에 3개다 별로인거같아서 여쭤봅니다. 감사합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
querydsl gradle 추가 오류..
compileQuerydsl 더블클릭하면 아래처럼 나오고 generated 폴더가 생기질 않습니다. 어떻게 하나요.. //querydsl 추가buildscript { dependencies { classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10") }}plugins { id 'org.springframework.boot' version '2.3.4.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE' id 'java'}apply plugin: "com.ewerk.gradle.plugins.querydsl"group = 'jpabook'version = '0.0.1-SNAPSHOT'sourceCompatibility = '11'configurations { compileOnly { extendsFrom annotationProcessor }}repositories { mavenCentral()}dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-devtools' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.6.2' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } //querydsl 추가 implementation 'com.querydsl:querydsl-jpa' //querydsl 추가 implementation 'com.querydsl:querydsl-apt'}test { useJUnitPlatform()}//querydsl 추가//def querydslDir = 'src/main/generated'def querydslDir = "$buildDir/generated/querydsl"querydsl { library = "com.querydsl:querydsl-apt" jpa = true querydslSourcesDir = querydslDir}sourceSets { main { java { srcDirs = ['src/main/java', querydslDir] } }}compileQuerydsl{ options.annotationProcessorPath = configurations.querydsl}configurations { querydsl.extendsFrom compileClasspath}
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
ArrayJson의 dto 관련
안녕하세요! 이번에 처음으로 jpa를 사용해서 토이프로젝트를 하고있습니다. 질문에 앞서서 이런 강의 만들어주셔서 너무 감사합니다 한눈에 쏙들어오고 이해가 됩니다 ㅎㅎ 제가 드릴 질문은 json방식이 Array방식일경우 dto에 자동으로 맵핑이 안되더라구요...어떤방식으로 해야자동맵핑이 될지 궁굼합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
주문내역..
안녕하세요? 강사님.. 여쭤볼게있습니다. 주문내역의 대표상품이 아닌 각각의 리스트를 뽑아보고 싶은데요.. 제가 생각한 쿼리는 select * from orders o inner join member m on o.member_id = m.member_id inner join order_item oi on o.order_id = oi.order_id; 결과는 이렇습니다. mybatis같은것에 익숙해서 이런식으로 vo를 만들어서 출력하곤했지만 jpql은 아직 많이 헷갈리네요.ㅠㅠ 일단 생각한 jpql은 아래와 같습니다. select o from Order o join o.member m join o.orderItems as oi 이렇게 하여 List<Order> 로 뽑아서 타임리프에 출력시 다중반복으로 출력을 면될거 같은데 출력이 아래 처럼 잘못 나오고있네요;; 감이 잘 오지 않는데 jpql을 제가 잘못 생각한것이지 어디가 잘못된건지 조언 좀 해주세요.. 역시 설명을 들으면 고개가 끄덕여지지만 직접해보면 갸우뚱 거리네요..ㅠㅠ;
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
강사님 에러 질문입니다. ㅠㅠ
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-11-17 16:24:19.845 ERROR 34406 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initDb': Invocation of init method failed; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:413) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1761) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:863) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.16.RELEASE.jar:2.1.16.RELEASE] at jpabook.jpashop.JpashopApplication.main(JpashopApplication.java:10) [classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.16.RELEASE.jar:2.1.16.RELEASE] Caused by: java.lang.NullPointerException: null at jpabook.jpashop.initDb$InitService.dbInit1(initDb.java:43) ~[classes/:na] at jpabook.jpashop.initDb$InitService$$FastClassBySpringCGLIB$$2eb0016.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:752) ~[spring-aop-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.1.17.RELEASE.jar:5.1.17.RELEASE] at jpabook.jpashop.initDb$InitService$$EnhancerBySpringCGLIB$$a95ed200.dbInit1(<generated>) ~[classes/:na] at jpabook.jpashop.initDb.init(initDb.java:29) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) ~[spring-beans-5.1.17.RELEASE.jar:5.1.17.RELEASE] ... 23 common frames omitted package jpabook.jpashop; import jpabook.jpashop.domain.*; import jpabook.jpashop.domain.Item.Book; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; // 총 주문 2 //-userA // JPA1 BOOK // JPA2 BOOK //-userB // SPRING1 BOOK // SPRING2 BOOK @Component @RequiredArgsConstructor public class initDb { private final InitService initService; @PostConstruct public void init() { initService.dbInit1(); } @Component @Transactional @RequiredArgsConstructor static class InitService { private EntityManager em; public void dbInit1() { Member member = new Member(); member.setName("userA"); member.setAddress(new Address("서울","1", "1111")); em.persist(member); Book book1 = new Book(); book1.setName("JPA1 BOOK"); book1.setPrice(10000); book1.setStockQuantity(100); em.persist(book1); Book book2 = new Book(); book2.setName("JPA2 BOOK"); book2.setPrice(20000); book2.setStockQuantity(100); em.persist(book2); OrderItem orderItem1 = OrderItem.createOrderItem(book1, 10000, 1); OrderItem orderItem2 = OrderItem.createOrderItem(book2, 20000, 2); Delivery delivery = new Delivery(); delivery.setAddress(member.getAddress()); Order order = Order.createOrder(member, delivery, orderItem1, orderItem2); em.persist(order); } } } 아마도 initDb 빈 생성에서 에러가 나는거 같은데 왜 그런지 모르겠습니다.
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
영상 11:00 ~ 11:30 내용 질문입니다.
OrderRepository에 직접 접근해서 findAll을 호출해서 DTO 객체를 만드는데요. 이메서드에는 @Transactional이 안붙어있어서 엔티티매니저가 메서드 호출이 완료되더라도 1차캐시가 끝나지않고 유지되는데 문제는 @Transactional를 붙일경우 메서드 호출이 끝나면 엔티티 매니저도 같이 종료시켜버리지만, 이 코드에서는 컨트롤러에서 엔티티 매니저를 close()를 명시적으로 호출하지 않는데 이럴경우 문제 없을까요?
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
엔티티 < -> DTO 관련 해서 조언을 듣고싶습니다.
안녕하세요. 엔티티와 DTO 변환 관련으로 한가지 조언을 듣고 싶어서 글 남깁니다. 저흰 mapstruct를 이용해서 DTO<->엔티티 변환을 자동화 하고 있고 그래서 대부분의 DTO가 엔티티와 변수명과 구조가 일치하고 필요하지 않은 정보는 제거하는 식입니다. 강의를 예로 들면 OrderDto에 name이 바로 있는게 아니라 Member객체로 래핑되어 있는 식이죠. 변환과정을 자동화해서 개발공수를 줄이는게 목적이었고 한 솔루션 내에서 프론트와 백앤드를 api 통신으로 연동하는 구조기 때문에 api spec를 고치는건 크게 문제가 안되기 때문에 이런 방식을 채택했습니다. 앞으로도 이런방식을 하는게 좋을지 아니면 강의에 나온거처럼 변환을 수동으로 해서 엔티티 spec 변경 시에도 응답값을 고정하는게 좋을지 조언을 듣고싶습니다. 감사합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
안녕하세요 질문이있습니다.
안녕하세요 김영한님 다름이 아니라 jpa 사용하면서 생긴 궁금증때문에 글을 남겨봅니다. 현재 Order를 추가로 생성하기 위해 API 에서 memberId, itemId를 받아와서 Member 조회 (select 1번) Item 조회 (select 1번) Order에 Set 후 추가 (insert 1번) 이런 식으로 되는 것 같은데요. 이렇게 insert 1번을 위해 select를 2번 날리는 방법이 일반적인 방법인가요? 테이블이 복잡하고 외래키 관계가 많아지면 사전 select가 3~4번 이상도 나갈 수 있을 것 같은데 이럴땐 일반 날쿼리를 써야하나 고민이 됩니다. 실무에서는 그냥 감수하고 select 날려서 쓰는지 궁금합니다. 한가지 질문이 더 있습니다. 만약 게시판에 댓글을 추가할 때 board.getComments.add(comment); 이런식으로 insert 한다고 치면 이것도 결국 불필요한 select가 나가야 하고 (LazyLoading 발동하면) 혹여나 그 select의 결과가 수백 수천개라면 (댓글이 수백 수천) 문제가 될 것 같고 사실 많은 경우는 자식 엔티티 갯수가 적다는게 보장되지 않는 경우일텐데 일반적으로 저렇게 add 하는 경우가 실무에서 잦은가요? 아니면 대부분은 그냥 comment.setBoard(board)해서 넣는 방식인가요? 감사합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
트랜잭션에 대해 질문이 있습니다.
안녕하세요 영한님, 해당 질문을 어디에 작성해야할지 몰라서 여기다가 남겨봅니다! 자바 ORM 표준 JPA 프로그래밍 책을 보다가 궁금점이 생겨서 질문남깁니다. P.580을 보면 logic() 메서드 위에 @Transactional 이 붙어있고 설명으로 메서드를 호출할 때에 트랜잭션을 먼저 시작하고 서비스가 끝나면 트랜잭션이 종료되었다고 설명되어있습니다. p.579 의 2번째 문단에서 또한 메서드와 엮어서 설명을 하고있습니다. 그렇다면, 클래스 위에 @Transactional를 붙여주었을 경우에는 해당 클래스가 호출될 때에 트랜잭션이 시작되게 되는 것인가요? 아니면 메서드 별로 다 붙게되는 것인가요? 만약 전자라면 트랜잭션의 종료 시점은 애플리케이션의 종료시점이 되는 것인지 궁금합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
EntityMager를 어떤식으로 넣어주는건가요?
안녕하세요! 여기서 EntityMager를 @Autowired할때 스프링 컨텍스트에서 매번 EntityMager를 생성하고 빈으로 등록해서 자동으로 주입시켜주는건가요?? (EntityMager는 공유되면 안되는 객체이므로 매번 생성하는걸로 이해했습니다.) 추가적으로 @DataJpaTest를 통해 테스트를 할때 @Entity 어노테이션과 @Repository 어노테이션이 붙은 클래스만 빈으로 등록되는걸로 알고 있습니다. 그러면 이때 EntityMager는 빈으로 등록되지도 않는데 어떻게 주입되는걸까요?
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Spring Data JPA에서 Page쿼리 작성도중 page의 size가 의도된 수넘어가면 타입에러가뜹니다 ㅠㅠ
실제 Comment도메인와 Query부분 로직입니다 문제는 Pageable의 size가 10이라고쳤을때 entity의 개수가 10개미만일경우는 에러가 발생하지않지만 딱 size개수 혹은 그이상이 될경우 페이지가 분리가 되지않고 위와같은 타입변환에러가 출력되었습니다 ( pageable의 size를 늘려줄경우 잘 작동합니다 페이지가 분리만 안되는거같아요 ) 이유를 잘모르겠어서 querydsl 로도 똑같이 작성해봤는데 이는 잘 작동하였습니다 혹시 이부분에 대해서 아시는게 있는지 여쭈어 보고싶습니다 ㅠㅠ 정리 : Spring Data JPA에서 entity의 개수가 size를 넘어갈경우 페이지가 넘어가지지않고 타입변환에러가 발생 ! ( 이전에는 공부할때 이런경험이 없었습니다 ) * 그리고 페치조인이아니라 일반 join을 할경우 entity의 기본생성자가 private타입이면 안되는건가요 ??
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
OneToMany 단방향 관련해서 궁금합니다.
안녕하세요. 좋은 강의 제공해주셔서 감사드립니다. OneToMany 단방향의 경우, 불필요한 insert, update가 발생할 수 있기 때문에 지양하는 방법이라 알고있는데요. @JoinColumn을 사용하여 insertable, updatable 값을 false로 설정하면, 위의 단점을 해결할 수 있을거 같은데요. 혹시 이외에 추가로 OneToMany의 단방향을 지양해야하는 이유가 있는지 궁금합니다!
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
양방향 1:1 관계 엔티티의 fetch join시 lazyloading 문제에 대해 질문드립니다.
안녕하세요. 영한님 강의를 보면서 실무에 처음으로 JPA를 도입해서 사용하고있습니다. 질문 내용은 페치조인시에 양방향으로 1:1 관계 매핑이 있는 엔티티의 경우 fetch type을 lazy로 설정하여도 즉시 조회 쿼리가 나가는 것 같아서 질문드립니다. 혹시 제가 설정을 잘못한 것인지 해결은 어떻게 해야할까요? 관계 구성은 간단하게 아래와 같습니다. Order 조회시 Member를 fetch join 하면Member 와 1:1관계인 MemberDetail 조회 쿼리가 즉시 수행됩니다. 제가 작성한 예제 코드도 공유해드리겠습니다. 테스트 코드에 있는 테스트 케이스를 실행 시켜보시면 조회쿼리를 확인하실수 있습니다. 예제 코드링크 git clone https://sangholee_dev@bitbucket.org/sangholee_dev/one-to-one-test.git 추가로 이건 강의 범주를 넘어서는 질문같긴한데 테이블 설계시 1:1 관계가 옳은 설계인지 궁금합니다. 영한님은 혹시 실무에서 성향이 다른 데이터를 저장할때 정규화하여 1:1 관계로 설계하시는지 아니면 테이블은 분리하지 않고 객체만 나눠서 처리하시는지 궁금합니다.
- 미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
No message available 404
안녕하세요 강사님 말씀하신 postman,intellij에서 실행 해봤는데 둘다 똑같은 오류가 뜨는데 왜 그럴까요..?
- 해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
컨트롤러 테스트
먼저 강의 내용과는 다른 질문 드려서 죄송합니다. 컨트롤러는 왜 테스트 해야 할까요? 컨트롤러 자체에는 비즈니스 로직이 없고 그저 서비스 계층에 위임하는 역할밖에 없는데 테스트 할 가치가 있을까요?? 서비스 계층 모두 테스트가 완료 되었다면 컨트롤러도 정확히 동작할거라고 예상 할수 있지 않나요?