30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
p6spy 두번 쿼리 나가는 문제
p6spy 설정 그대로 했는데, 같은 쿼리가 두번 나가는데요 이 문제를 해결할 수는 없나요?
- 미해결실전! Querydsl
sum에 if문을 사용할 수 있나요?
안녕하세요 강의를 들으면서, querydsl을 적용하여 프로젝트를 만들고 있습니다. 현재 만드는 프로젝트에서 a, b 케이스의 카운트와 a케이스만의 카운트, b케이스만의 카운트 a, b 케이스의 총합과 a케이스만의 총합, b케이스만의 총합을 구하려고 합니다. 카운트의 경우, eq()로 조건을 걸어서 원하는 값으로 추출이 가능한 것 같은데 총합의 경우, 전체 총합의 경우 외에 if문같은 조건을 구하는 방법을 구글링해보아도 확인할 수 없어서 질문드립니다. ueryFactory.select(income.count().as("totalCase"), income.isAcupuncture.eq(true).count().as("acupunctureCase"), income.isAcupuncture.eq(false).count().as("medicineCase"), income.amount.sum().as("totalAmount"), select count(case when is_acupuncture = 1 then 0 end) as acupunctureCase, sum(if(is_acupuncture = 0, amount, 0)) as medicineAmount, <<<<<<<< sum(amount) as totalAmount from income where income.patient_id = 4; querydsl에서도 sum 문법에 if문으로 처리하는 방법이 있을까요?
- 미해결실전! Querydsl
컴파일 관련 에러
test 중에 계속 1. HikariPool-1 - Exception during pool initialization. 2.2022-04-10 22:13:08.388 ERROR 10156 --- [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] 3.2022-04-10 22:13:08.382 WARN 10156 --- [ main] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata 4.022-04-10 22:13:08.388 WARN 10156 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] 이러한 에러가 뜹니다... 구글링을 해봐도 yml 문제도 아닌거같고 알려주시면 감사하겠습니다..
- 미해결실전! Querydsl
db h2 관련 오류입니다 ㅠㅠ
mv 파일만드려고 먼저 이렇게 했을때는 연결이 되는데 table 생성을 위해서 embeded로 tcp;localhost주소로 연결하게되면 이런식으로 연결 자체가 안되는데 도저히 원인을 모르겠습니다... 다른 프로젝트는 또 연결이 되고 제각각으로 에러만 발생하네요 ㅠㅠ
- 미해결실전! Querydsl
applyPagination 메소드 관련 질문입니다.
JPAQuery를 raw 타입으로 쓰지 말고 <T>를 붙여서 쓰면 더 좋지 않나요? protected <T> Page<T> applyPagination(Pageable pageable, Function<JPAQueryFactory, JPAQuery<T>> contentQuery) { JPAQuery<T> jpaQuery = contentQuery.apply(getQueryFactory()); List<T> content = getQuerydsl().applyPagination(pageable, jpaQuery).fetch(); return PageableExecutionUtils.getPage(content, pageable, jpaQuery::fetchCount);}
- 해결됨실전! Querydsl
Sort 질문있습니다.
Querydsl 4RepositorySupport에 Sort를 처리해주는 로직이 없는데 이건 따로 구현해야하는건가요? Querydsl4RepositorySupport에서 @Autowiredpublic void setEntityManager(EntityManager entityManager) { Assert.notNull(entityManager, "EntityManager must not be null!"); JpaEntityInformation entityInformation = JpaEntityInformationSupport.getEntityInformation(domainClass, entityManager); SimpleEntityPathResolver resolver = SimpleEntityPathResolver.INSTANCE; EntityPath path = resolver.createPath(entityInformation.getJavaType()); this.entityManager = entityManager; this.querydsl = new Querydsl(entityManager, new PathBuilder<>(path.getType(), path.getMetadata())); this.queryFactory = new JPAQueryFactory(entityManager);} 이 부분이 스프링 데이터에서 제공하는 Pageable안에 있는 Sort를 사용할 수 잇도록 설정한 것이라고 하셨는데 그럼 MemberTestRepository에서 public Page<Member> applyPaginationWithSort(MemberSearchCondition condition, Pageable pageable) { return applyPagination(pageable, contentQuery -> contentQuery .selectFrom(member) .leftJoin(member.team, team) .where(usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()))) .orderBy(pageable.getSort());} 와 같이 pageable.getSort()로 Sort값을 가져와 orderBy절에서 사용하면 되는건지 궁금합니다
- 미해결실전! Querydsl
다른 스키마 테이블 조인
querydsl로 현업하고 있는데 궁금한 사항이 있습니다. querydsl은 다른 스키마에 있는 테이블끼리 조인하고 싶은 경우에 사용이 불가능한가요?
- 미해결실전! Querydsl
querydsl cannot find symbol
현재 build.gradle 설정인데 어떻게 고치더라도 cannot find symbol 에러가 발생합니다 (Q파일이 생성이 안됩니다, 폴더까지 모두 생성이 안됩니다) 도움 부탁드립니다! //querydsl 추가buildscript { ext { queryDslVersion = "5.0.0" }}plugins { id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' //querydsl 추가 id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" id 'java'}group = 'team'version = '0.0.1-SNAPSHOT'sourceCompatibility = '11'repositories { mavenCentral()}dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' //querydsl 추가 implementation "com.querydsl:querydsl-jpa:${queryDslVersion}" annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}" implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8' // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '2.6.3' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' runtimeOnly 'mysql:mysql-connector-java' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test'}tasks.named('test') { useJUnitPlatform()}//querydsl 추가 시작def querydslDir = "$buildDir/generated/querydsl"querydsl { jpa = true querydslSourcesDir = querydslDir}sourceSets { main.java.srcDir querydslDir}configurations { compileOnly { extendsFrom annotationProcessor } querydsl.extendsFrom compileClasspath}compileQuerydsl { options.annotationProcessorPath = configurations.querydsl}//querydsl 추가 끝
- 해결됨실전! Querydsl
동적쿼리 합칠때 NPE 에러
안녕하세요. 영한님 이전 강의와 질문게시판을 보며 BooleanExpression 조건들을 and 혹은 or 로 묶을수있는 장점이 있다는것을 보았습니다. 그런데 NULL 체크가 따로 필요하다고 하셨고 그에대한 답변으로 private Predicate allEq(String usernameParam, Integer ageParam) { return usernameEq(usernameParam).and(ageEq(ageParam));}private BooleanBuilder usernameEq(String usernameParam) { if(usernameParam == null) return new BooleanBuilder(); return new BooleanBuilder(member.username.eq(usernameParam));}private BooleanBuilder ageEq(Integer ageParam) { return new BooleanBuilder(ageParam != null ? member.age.eq(ageParam) : null);} 이러한 형태로 null 을 확인하면 된다고 답변해주셨습니다. 그런데 이답변을 보면 기존 반환타입이 BooleanExpression 아닌 BooleanBuilder를 들어간것을 확인했습니다. BooleanExpression은 구현체 생성이 불가능하여 BooleanBuilder를 생성하신거 같은데 질문입니다. 1. 그럼 결과적으로 null 처리 까지 하기위해서는 where절 파라미터 사용시에 BooleanExpression 타입 대신 BooleanBuilder 를 반환타입으로 생성하는게 맞는건지 궁금합니다. 2. 제가 생각한 1번의 내용이 아니라면 BooleanExpression 타입을 이용했을때는 null체크를 어떤식으로 해야하는지 궁금합니다. 감사합니다!
- 미해결실전! Querydsl
페이징에 대해서 문의드립니다.
정말 좋은 강의 감사합니다. 다름이 아니라 querydsl로 페이징 처리를 하게 될 경우 기본이 0부터 시작이 되는데 web 화면에서 작업을 해 보니 <ul> <li> <a th:href="@{/list(searchType=${param.searchType}, keyword=${param.keyword}, page=${userList.getNumber() - 1})}"> <i class="fas fa-angle-double-left"></i> </a> </li> <li th:each="i : ${#numbers.sequence(0, userList.getTotalPages() - 1 )}"> <a th:href="@{/list(searchType=${param.searchType}, keyword=${param.keywrod}, page=${i})}" th:classappend="${i == (userList.getNumber() + 1) ? 'text-blue-600 bg-blue-50 border-blue-300' : ''}" th:text="${i + 1}">1</a> </li> <li> <a th:href="@{/list(searchType=${param.searchKeyword}, keyword=${param.keyword}, page=${userList.getNumber() + 1})}"> <i class="fas fa-chevron-right"></i> </a> </li> <li> <a th:href="@{/list(searchType=${param.searchType}, keyword=${param.keyword}, page=${userList.getNumber() + 1})}"> <i class="fas fa-angle-double-right"></i> </a> </li> </ul> 위와같이 작업을 했는데 하단에 페이지 번호는 1번부터 보여지는데 실제 URL로 보여지는 주소는 ?searchType=&keyword=&page=0 이런식으로 페이지 번호가 0번부터 시작이 됩니다. 그리고 하단의 페이지 번호를 클릭을 해도 당연히 4페이지를 클릭하면 URL에는 page=3으로 표시가 되는데 이 표시되는 값을 변경을 할려면 어떻게 해야할까요??구현하려고 하는 것은 하단의 4페이지를 클릭을 하면 4페이지의 정상적인 데이터가 보여지고, 상단의 URL에도 page=4로 표시가 되게 하려고 하는데 잘 안되네요. 어떤식으로 수정을 해 줘야 할까요?
- 미해결실전! Querydsl
select절 서브쿼리 tuple에서 읽는방법
안녕하세요 영한님. 밑에 비슷한 질문이 있었는데 해결이 되지않아 질문드립니다. //모든이름과 평균나이 출력QMember memberSub = new QMember("memberSub");List<Tuple> result = queryFactory .select(member.username, JPAExpressions .select(memberSub.age.avg()) .from(memberSub) ) .from(member) .fetch();for (Tuple tuple : result) { System.out.println(tuple.get(member.username)); System.out.println(tuple.get(1, Double.class));} 강의에서 코드인데요 여기서 평균나이값을 tuple에서 뽑고싶어서 tuple.get(memberSub.age.avg()) 로 뽑아봤는데 값이 null이 나옵니다. 그래서 현재는 Index와 클래스로 뽑긴했는데 member.username처럼 바로뽑는법이 있을까요? 항상 감사합니다.
- 해결됨실전! Querydsl
query 작성 문의드립니다.
@Slf4j@RestController@RequestMapping("/query")public class QueryDslBasicController { @Autowired EntityManager em; @GetMapping("/find") public String find() { Account result = em.createQuery("select a from Account where a.email = :email", Account.class) .setParameter("email", "test@gmail.com") .getSingleResult(); log.info("result ={}", result); return ""; }} 위와같이 쿼리를 작성을 했는데 오류가 납니다. 아래와 같이 오류가 나는데 무슨 이유에서 오류가 날까요?? Account라는 도메인에 email이라는 값도 있고,DB에도 해당 테이블의 해당 필드도 있고, 검색을 할려는 값도 정상적으로 들어가 있습니다. 2022-03-15 13:16:39.063 ERROR 75178 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: Unable to resolve path [a.email], unexpected token [a] [select a from com.example.domain.Account where a.email = :email]] with root cause org.hibernate.QueryException: Unable to resolve path [a.email], unexpected token [a] at org.hibernate.hql.internal.ast.tree.IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:292) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.tree.IdentNode.resolve(IdentNode.java:143) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.tree.DotNode.resolveFirstChild(DotNode.java:172) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:711) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.addrExpr(HqlSqlBaseWalker.java:5075) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1304) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4778) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4244) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2166) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:832) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:626) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:330) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:278) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:636) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:748) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:848) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:114) ~[hibernate-core-5.6.5.Final.jar:5.6.5.Final] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_291] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_291] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_291] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_291] at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy109.createQuery(Unknown Source) ~[na:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_291] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_291] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_291] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_291] at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.16.jar:5.3.16] at com.sun.proxy.$Proxy109.createQuery(Unknown Source) ~[na:na] at com.example.EXAM.QueryDslBasicController.find(QueryDslBasicController.java:22) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_291] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_291] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_291] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_291] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.16.jar:5.3.16] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.16.jar:5.3.16] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.58.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:219) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.6.2.jar:5.6.2] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.16.jar:5.3.16] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.16.jar:5.3.16] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.58.jar:9.0.58] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.58.jar:9.0.58] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_291] DB 연결도 해줬고, 기본적인 JPA 쿼리는 다른 컨트롤러에서는 잘 동작을 합니다.
- 미해결실전! Querydsl
where 절 parenthesis 추가 문의
안녕하세요 where 절에서 ( A and B and C) or ( D and E and F) 조건을 처리해야하는 상황인데 다음과 같은 방법으로 하여도 쿼리가 위와 같이 나가지 않아서 문의드립니다. 1. Ops.wrapper 사용했지만 실제로는 풀려서 나감 2. 검색하여 나온 대부분의 해결책 where((A.and(B).and(C).or(D.and(E).and(F))) 하지만 실제 쿼리는 괄호가 다풀려서 나감 native 없이 querydsl에서는 불가능한 것인가요? 감사합니다.
- 미해결실전! Querydsl
DTO 사용 범위에 대한 질문
강의에서 일반적으로 repository에서 만든 dto를 service와 controller에서 사용한다고 하셨습니다. 그런데 이전 강의에서 tuple은 repository계층에서만 사용하고 service나 controller에서 사용하는건 비추한다고 하셨습니다. tuple의 경우엔 하부 구현기술에 class이니 앞단에서 알면 좋지 않다.(jpa를 바꾸게 되는 경우 수정할 로직이 많아진다) 라고 이해했는데요. dto도 비슷하지 않을까 생각이 들었습니다. repository에서 만든 dto를 바꾸게 될 경우 앞단에서 수정할 로직이 많으니까요. dto와 tuple(resultset 등)은 다르게 보아야 하는걸까요? repository에서 만든 dto는 repository나 service에서까지만 사용하고 controller에서는 새로운 dto로 매핑하는게 맞을까요? 아니면 repository는 뒷단(안쪽) 영역이니 앞쪽에서 의존성을 가져가도 된다고 생각하는게 맞을까요?
- 미해결실전! Querydsl
BooleanBuilder, dto 변환, fetchCount() 질문 있습니다
강의 너무 감사합니다~ 다 듣고 여러가지 시도해보니 3가지 의문점이 있어서 질문드립니다! 1. where에 BooleanBuilder 사용보다는 BooleanExpression을 사용하는게 좀 더 좋다는 강의를 들었습니다. https://www.inflearn.com/questions/94056 그런데 위 링크를 보면 강의에서 where(builder)를 쓰시는 것과 달리 BooleanBuilder를 강의에서 소개해주신 BooleanExpression 방법처럼 체인해서 사용하고 계십니다. BooleanBuilder를 사용하면 BooleanExpression과 달리 where절에 전체 null일 경우 예외가 터지는 경우도 해결할 수 있는 것으로 보이는데 링크에서 사용하신 방법을 쓰는게 바람직할까요? 2. domain을 dto로 변환하는 과정에서 domain에 있지 않은 좋아요 갯수, 좋아요 여부 등의 추가 변수들을 어디에서 처리하면 좋을까요? java service쪽에 가져와서 해결하는게 좋을까요, 아니면 repository에서 querydsl로 조회하고 모두 가공한 뒤에 그 결과를 service쪽에 가져오는게 나을까요? 엔티티 편의 메서드를 사용하면 원하는 결과를 바로 dto로 조회하지 못하므로 domain을 불러와서 변경 작업 후 dto로 또다시 변경해줘야한다고 생각이 들어서 깔끔하게 처리하는 방법이 있나 궁금합니다 3. 카운트 쿼리를 날릴 때 성능을 위해서 fetchResults()대신에 fetch()와 fetchCount()를 따로 날리면 좋다고 배웠습니다. 개인적으로 이 경우 그냥 fetch()로 받아온 List를 .size()로 count를 가져오는게 편하다고생각되는데 따로 fetchCount()로 조회하는 이유가 있을까요?
- 미해결실전! Querydsl
벌크연산 후 em.flush(), em.clear()에 동시성 이슈는 없나요?
안녕하세요 영한님. 강의 정말 잘 듣고 있습니다. 감사합니다. 궁금한것이 생겨 다른 질문들도 확인해 보았는데 궁금증이 해소되지 않아 질문드립니다. ㅜ 질문 내용은- 벌크연산의 JPQL 쿼리 직후(em.flush() 실행 전),- 다른 쓰레드에 의해 영속성 컨텍스에서 엔티티 수정이 이루어지면, - em.flush()에 의해 DB가 영속성 컨텍스 내용으로 덮어씌워져 벌크연산 결과가 사라질 수 있지 않은지? 입니다. 그리고 문제가 있다면 어떻게 해결해야 하는지 알고싶습니다. 예시) 시간순서로 나열했습니다. member1의 age는 20이라고 가정하겠습니다. Thread1 Thread2 member1 조회 (영속상태가 됨) QueryDSL로 벌크연산 (DB 수정, age 를 2배로 변경) (JPQL로 인한 flush가 실행되나 아직까지 DB와 영속성 컨텍스트 차이 없음) member1 수정 (age에 1 추가) (dirtycheck 체크됨) em.flush(), em.clear() (여기서 문제발생?) em.flush()가 실행되는 시점에 member1이 수정되어 있으니 영속성 컨텍스트에 있는 member1의 age값 21이 DB에 있는 age값 40을 덮어쓰지 않나요? 만약 이런 문제가 발생한다면 이를 막기위해 어떻게 해야 하나요?
- 미해결실전! Querydsl
QueryDsl 바인드 변수 질문있습니다.
안녕하세요. 좋은 강의 내주셔서 감사합니다. 다름이 아니라 사용자가 전달한 DTO 프로퍼티가 아니라 실행되는 SQL내에서 항상 고정 값으로 사용되는 where 절 조건이 있을 경우 최적화를 위해 해당 값을 Parameter 바인딩 형식이 아니라 Literal 값으로 SQL 구문에 포함 시키고 싶습니다. 혹시 입력 값을 Literal로 포함시킬 수 있는 방법에 대해서 여쭙고 싶습니다.
- 미해결실전! Querydsl
DTO변환 Projections.bean 관련 질문입니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요. JPA를 넘어 QueryDsl까지 잘 보고 배우고 있습니다. QueryDsl을 사용한 DTO변환 1단계인 Projections.bean 을 사용중에 강의에서는 DTO 클래스의 Getter와 Setter를 이용하여 변환을 한다고 하셨었습니다. 영상에서는 getter와 setter가 포함되어있는 @Data 어노테이션을 사용하였었습니다. 그런데, 여러가지 실험 차원에서 @Data를 빼고도 잘 작동이 되어 그 이유가 궁금합니다 @NoArgsConstructorpublic class MemberDto { private String username; private int age; public MemberDto(String username, int age) { this.username = username; this.age = age; }} /** * DTO 조회하기 방법 1. QueryDsl : 프로퍼티 접근 * DTO에 GETTER, SETTER가 존재해야함. */@Testpublic void findDtoBySetter() { List<MemberDto> result = queryFactory .select(Projections.bean(MemberDto.class, member.username, member.age)) .from(member) .fetch(); for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); }}결과-> /* select member1.username, member1.age from Member member1 */ select member0_.username as col_0_0_, member0_.age as col_1_0_ from member member0_ memberDto = study.querydsl.dto.MemberDto@35329a05 memberDto = study.querydsl.dto.MemberDto@36c783ca memberDto = study.querydsl.dto.MemberDto@17136390 memberDto = study.querydsl.dto.MemberDto@273293c8
- 미해결실전! Querydsl
null처리 관련 질문드립니다.
안녕하세요. 항상 좋은 강의 제공해주셔서 진심으로 감사의 말씀 드립니다. 강사님께서 약 8분 17초경에 이런 경우에는 null처리를 따로 해주어야한다고 말씀하셨는데 '이런 경우'라고함은 어떤 상황을 말씀하시는건가요..?조금 찾아보니(allEq를 만들 때) usernameEq(username)이 null이라면 체이닝이 되지 않는 상황이 생기는 것을 확인하였습니다. 이 경우를 말씀하시는 것인가요? 이것 외에도 이런 상황에서 null과 관련하여 발생할 수 있는 상황들을 말씀해주시면 학습하는데 많은 도움을 받을 수 있을 것 같습니다. 감사합니다 :)
- 미해결실전! Querydsl
안녕하세요 DTO반환 관련 질문있습니다.
안녕하세요 영한님 강의 재밋게 잘보고 있습니다. 다름이 아니라 회사에서 QueryDSL 처음 도입을 하려고했는데 멀티?프로젝트로 현재 구성이 되어있습니다. 예를들면 Porjects projcet1 projcet2 projcet1Common 이런식으로 되어있고 projcet1 / projcet2 는 projcetCommon을 참조하는 구조입니다. 모든 Entity는 projcetCommon를 참조하고 있습니다. 근데 여기서 질문드리고 싶은것은 projcetCommon에는 공통으로 사용하는 util이나 Entity만 있고 각각 project마다 DTO는 다르게 사용을 합니다. 이유는 Entity는 자주 변화가 없지만 DTO는 자주 변할 가능성이 있기때문에 각각사용을 합니다. 제가 queryDSL로 서브쿼리를 사용하여 alias를 줘서 보내는 컬럼이 있는데 그거에 맞는 DTO는 project1 에 있다보니 Entity에 @Transient를 주어서 Entity반환을 해서 사용합니다.... Common에 DTO를 만드는것 말고는 다른 방법이 없을까요..?