월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
@Transaction에 대해서 질문드드립니다.
안녕하세요? 강사님. 항상 좋은 강의 잘 보고 있습니다. 이번강의를 보면서 에러가 발생하였습니다. Member member = new Member("member1", 10);memberRepository.save(member);Member findMember = memberRepository.findById(member.getId()).get();assertThat(findMember).isEqualTo(member); assertThat부분에서 <"Member(id=1, username=member1, age=10) (Member@1b444b5)"> to be equal to: <"Member(id=1, username=member1, age=10) (Member@5a1a20ae)"> but was not. Expected :Member(id=1, username=member1, age=10) Actual :Member(id=1, username=member1, age=10) 이러한 에러가 발생했습니다. 알고보니 @Transaction 어노테이션을 선언을 안해서 그랬습니다. member와 findMember의 메모리 주소가 달라서 에러가 발생한것 같은데 메모리가 주소가 왜 다른지 잘 이해가 안됩니다. meber객체를 save 하면서 영속성 컨텍스트에 담기고 findMember는 영속성컨텍스트에 담겨있는 member인것이 아아니라 새로 select문을 날려서 디비에서 조회한 값이더라구요( @Transactional이 없을 때 로그를 통해서 확인하였습니다) @Transactional을 선언 하고 save 후 em.flush(); em.clear();를 해준것과 같은 현상이 나더라구요. @Transactional이 롤백외에도 어떠한 기능이 있길래 이러한 현상이 나타나는지 알고 싶습니다. 감사합니다.
- 미해결실전! Querydsl
union 질문 입니다.
안녕하세요 강사님 강의 잘 듣고 있습니다. jqpl 에서는 union 자체를 지원하지 않는 걸로 알고 있는데 지원하지 않는 이유가 union으로 문제를 해결하는게 좋은 로직이 아니어서 일까요? union을 써서 해결해야 하는 것들은 어떤 식으로 해결하는지 궁금합니다!
- 미해결실전! Querydsl
쿼리문 작성 질문입니다!
안녕하세요 강사님! 강의 항상 열심히 듣고 있습니다. 이번에 스프링을 배운김에 토이 프로젝트를 하나 하고 있습니다. 기능중에 준비된 랜덤단어 두 개 로 유저의 닉네임을 랜덤으로 지어주는 기능을 만들려고 합니다. 그래서 랜덤단어X랜덤단어를 만드는거는 쉽지만 user table 에 이미 있는 닉네임이면 클라에 주기 전에 서버에서 먼저 거르는 작업을 하고자 합니다. 랜덤단어 하나를 만들어서 DB에 존재하는지 검사하는 로직을 통과할때까지 while문으로 돌릴까 생각하였지만 db와 연결을 너무 많이 하게 될 것 같아 포기하고 sql문으로 해결할 수 없는지 생각해 보았습니다. 그래서 생각한게 랜덤단어가 들어있는 테이블을 두 개 만들어서 세타조인을 해서 하나의 테이블을 만들고, 유저테이블에서 나온 닉네임과 대칭 차집합을 통해 아직 만들어지지 않은 닉네임들을 후보까지 안전하게 10개를 뽑아서 클라에 넘겨주자는 생각을 했습니다. 그래서 대칭 차집합 쿼리를 찾아보니 SELECT str FROM ( SELECT str FROM tableA UNION ALL SELECT str FROM tableB ) AS tmp GROUP BY str HAVING COUNT(*)=1 이렇게 구현할 수 있다는 것을 알게 되었습니다. 근데 jpql은 FROM 절에 서브쿼리를 적을 수 없어 이것을 구현할 수 없다고 생각했습니다. 혹시 뭔가 다른 구현이 가능한 방법이 있을까 해서 질문 드립니다!
- 미해결실전! Querydsl
jpaqueryfactory 권장 이유를 알 수 있을까요?
안녕하세요. 강의 정말 잘 듣고 있습니다!! 강의를 보면서 jpaqueryfactory를 최근 버전에서 권장하신다고 하셨는데, 혹시 왜 권장되어지고 있는지 이유를 알 수 있을까요?
- 미해결실전! Querydsl
Full outer join 질문있습니다 !
Querydsl로 Full outer join이 가능할까요?
- 미해결실전! Querydsl
join 여러번 할 경우 질문있습니다.
여러 엔티티들과 조인하고 싶으면 .join().join() 이렇게 조인 뒤에다 조인 써서 하면 되나요?
- 미해결실전! Querydsl
select 절에서 필드와 집계함수 동시 나열 문제
강의 예문) List<Tuple> result = queryFactory .select(member.username, JPAExpressions .select(memberSub.age.avg()) .from(memberSub) ) .from(member) .fetch(); 안녕하세요. select(member.age.avg(), member.age.max()) from(member)은 가능한데 위 예문을 select(member.username, member.age.avg()) .from(member)으로 바꿀 수 없는 이유가 무엇일까요?쿼린이라 질문이 초보적인 점 부디 이해를 부탁드립니다.
- 미해결실전! Querydsl
콘솔의 결과 코드와 작성한 jpql 간 차이
강의 예제) 회원과 팀을 조인하면서 팀 이름이 teamA인 팀만 조인, 회원만 모두 조회 위 예제를 가지고 querydsl을 작성하기 전에 먼저 선생님이 JPQL로 작성해주신 구문은 다음과 같은데요. JPQL: select m, t from Member m left join m.team t on t.name = 'teamA'; 테스트 결과 화면 설명해주실 때 콘솔 주석의 jpql은 with가 들어있더라구요. 이 둘이 다른 이유가 있을 것 같은데 무엇 때문일까요? /* select member1, team from Member member1 left join member1.team as team with team.name = ?1 */
- 미해결실전! Querydsl
예문 쿼리 결과 정렬 순서와 containsExactly
안녕하세요! 선생님의 보배로운 강의 넘나 잘 듣고 있습니다. 강의 중에 containsExactly("teamA", "teamB")에 관해 질문이 있는데요. 찾아보니 값만 맞으면 되는 게 아니라 순서도 맞는지 확인하는 것 같은데, 이때 "teamA", "teamB"가 맞으려면 오름차순 정렬이 되어야 하잖아요? 하지만 select ftom where문의 결과는 기본적으로 어떻게 정렬될지 알 수 없는 것 아닌지요?
- 미해결실전! Querydsl
querydsl와 jdbctemplate 의 성능 비교 질문입니다.
안녕하세요 김영한님, querydsl 강의를 수강중인 학생입니다. 수강중에 문득 querydsl 은 동적으로 query 를 만들어주는 도구이다 보니 jdbctemplate 와 querydsl 간의 성능에 따른 차이가 있을것으로 생각되어 검색을 해보았습니다. 아래의 stackover flow 에 기재된 내용으로는 약 6배 정도 차이가 난다고 적혀있는데요 실무에서 이정도의 성능적인 차이가 발생하는지 궁금합니다. https://stackoverflow.com/questions/38123217/performance-tests-between-querydsl-sql-vs-jdbctemplate 만약에 이렇게 성능적으로 차이가 많이 발생하게 된다면 실제 service 단계에서도 서버의 메모리나 확장에 관해서도 많은 리소스가 추가로 투입이 되어야할것 같습니다. 최근들어 쿠버네티스를 통해서 이러한 성능적이슈를 효율적으로 관리한다고 귓동냥으로 듣기는 했습니다. 저의 생각으로는 휴먼리소스를 투입해서 jdbctemplate 으로 코딩 할것인가 아니면 자본을 투입하여 문제를 해결할것인가의 문제로 보여 어떤것에 가치를 두냐에따라 답이 다른것같습니다. 이러한 jpa, jdbctemplate 의 성능적인 관점에서 김영한님 생각이 궁금합니다. 약간은 수업의 방향에 어긋나는것 같은 질문이라 조심스럽습니다... (ps. jpa 와 querydsl 의 성능을 비교하게 비슷할까요..? )
- 미해결실전! Querydsl
Spring Sort를 QueryDSL 변환 적용하는 방법 문의
안녕하세요. 강사님 QueryDSL 재미있게 배웠습니다. 정렬기준을 아래와 같이 받았을 때 pageable 파라미터를 이용해서 QueryDSL에 적용하는 방법에 대해서 고민입니다. 정렬기준 입력 형태: URI?sort=field1,asc&sort=field2,desc org.springframework.data.domain.Sort 방법1. pageable 값을 얻어와 직접 queryDSL에 OrderSpecifier로 지정 if (pageable != null) { query.offset(pageable.getOffset()); query.limit(pageable.getPageSize()); for (Sort.Order o : pageable.getSort()) { PathBuilder<Object> orderByExpression = new PathBuilder<Object>(Object.class, "object"); query.orderBy(new OrderSpecifier(o.isAscending() ? com.mysema.query.types.Order.ASC : com.mysema.query.types.Order.DESC, orderByExpression.get(o.getProperty()))); } } 방법2. applyPagination() 함수로 매핑 getQuerydsl().applyPagination(pageable, jPQLQuery); 결과적으로 방법2가 더 깔끔해 보이는데 원본 엔티티와 DTO객체가 달라서 org.hibernate.hql.internal.ast.QuerySyntaxException이 발생하는 이슈가 있습니다. 현재까지 결론은 방법1을 사용해야할 것으로 보이는데 더 좋은 방법을 아시는지 문의드립니다. 감사합니다.
- 미해결실전! Querydsl
where( , ) 사용시 OR 조건을 사용하는 방법
안녕하세요. return jpaQueryFactory .select(member) .from(member) .where(usernameEq(usernameParam), ageEq(ageParam)) .fetch() 위와 같이 where안에 콤마(,) 를 사용하면 and 조건으로 연결이 되는데요. 혹시 별도의 함수(OR조건으로 묶을수 있도록)를 만들지 않고 간단하게(콤마를 사용하는것 처럼) or 조건으로 연결하는 방법도 있을까요?
- 해결됨실전! Querydsl
Dto로 조회 관련 질문드립니다!
안녕하세요 팀장님 강의 내용을 토대로 다양하게 혼자 연습해보고 있는데, Dto로 조회하는 과정에서 오류가 계속 발생했는데 어떤식으로 해결해야될지 몰라서 질문 남깁니다.! Member - Team 관계에서 Team을 Dto로 조회하는 과정입니다. 우선 Dto말고 Tuple로 조회했을때는 정상 동작했습니다. 1. Tuple 조회 ( 정상 동작) @BeforeEachpublic void setup() { queryFactory = new JPAQueryFactory(em); Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); em.persist(teamA); em.persist(teamB); Member member1 = new Member("member4", 10, teamA); Member member2 = new Member("member4", 20, teamA); Member member3 = new Member("member4", 30, teamB); Member member4 = new Member("member4", 40, teamB); Member member5 = new Member("member5", 40, teamB); em.persist(member1); em.persist(member2); em.persist(member3); em.persist(member4); em.persist(member5); em.flush(); em.clear();} List<Team> fetch = queryFactory .selectFrom(team) .join(team.members, member).fetchJoin() .fetch();System.out.println("fetch.get(0).getMembers() = " + fetch.get(0).getMembers()); 정상동작 2. Dto 조회 @Datapublic class TeamDto { private String name; private List<MemberDto> members = new ArrayList<>();} @Datapublic class MemberDto { private String username;} List<TeamDto> result = queryFactory .select(Projections.fields(TeamDto.class, team.name.as("name"), Projections.fields(MemberDto.class, member.username ).as("members") ) ) .from(team) .join(team.members, member).fetchJoin() .fetch();System.out.println("dto = " + result.get(0).getMembers()); 실행결과 not compatible with java.util.List이 발생했습니다. ㅠㅠ 이것저것 바꿔가면서 다양하게 시도해봤는데도 계속 오류가 발생했습니다.. 어떤 식으로 변경해야 될까요? 추가로 시도하면서 느낀게 한 개 이상의 Dto가 있을 경우 코드의 가독성이 너무 떨어지게 되더라고요. 혹시 팀장님께서는 여러개의 Dto를 조회할 때 따로 사용하는 방식이 있으신가요?
- 해결됨실전! Querydsl
(해당 영상직접 연관x) 강의 전반 package 구성 질문
삭제된 글입니다
- 미해결실전! Querydsl
Left join 에서 on절에 BooleanExpress 적용 가능할까요?
안녕하세요. QueryDsl에서 left join에서 동적으로 on절을 만들 수 있나요? .selectFrom(lesson).leftJoin(lesson.enrollmentLessons, enrollmentLesson).on(eqTutee(condition)) 위와 같이 사용 시 잘 동작중인데 eqTutee가 null 인 경우 에러가 발생합니다. 물론 동적으로 if를 사용해서 분기를 할 수 있긴 한데 좀 더 쉽게 할 수 있는 방법이 있을까 해서 문의드립니다.
- 해결됨실전! Querydsl
Querydsl 적용시 service와 seeviceImpl
안녕하세요 mybatis환경에서 변경해보고자 배우고 있는 중입니다. 다름이 아니라 예시에서 보여주신 소스를 보면 service나 serviceimpl없이 바로 controller에서 repo를 호출하는 형식으로 되어있는데, 실무에서도 이와 같이 사용하는지 아니면 controller service serviceimpl repo repoimpl 형식으로 쓰는지 궁금합니다. 이른 시간에 질문 올려 죄송합니다
- 해결됨실전! Querydsl
JPAQueryFactory 의존성 질문드립니다..!
안녕하세요~ 강사님~수업시간에 JPAQueryFactory를 @Bean으로 등록하셨는데 이걸 주입받은 객체에서 다른 객체로 넣어줘도 멀티쓰레드 환경에서 문제가 없을까요?? 샘플 코드 public interface FruitBehavior { List<FruitList> getFruitList();} @RequiredArgsConstructorpublic class BananaRepository implements FruitBehavior { private final JPAQueryFactory queryFactory; @Override public List<FruitList> getFruitList() { queryFactory .selectFrom(fruit); }} @RequiredArgsConstructorpublic class TestRepositorySupport { private final JPAQueryFactory queryFactory; private final Map<String, FruitBehavior> map = new HashMap<>(); void doSomething() { map.put("Banana", new BananaRepository(queryFactory)); // 여기!!! }} 대충 이런식으로 ...TestRePositorySupport에서 주입받은 queryFactory를 BananaRepository를 만들때 넣어줘도 문제가 없을까요?실행해봤는데 결과는 잘 출력되는데.. 혹시나 싱글턴이 깨지거나 다른 이슈들이 생기진 않을까 궁금합니다..!!
- 해결됨실전! Querydsl
테스트 오류 질문드립니다!!
안녕하세요 강사님~ RepositoryCustom - RepositoryCustomImpl 구현하고 Repository에서 RepositoryCustom상속하는 커스텀 있잖아요~ 여기서 기존에 @SpringBootTest로 실행되는 통합테스트를 @DataJpaTest로 변경하니까 변경한 모든 테스트가 깨지더라고요.. 빈을 생성하는 과정에서 오류가 나더라고요 ㅜㅜ `Error creating bean with name 'memberRepositoryCustomImpl' defined in files ~ ` `No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' available: expected at least 1 bean which qualifies as autowire candidate` 단위 테스트에서는 기본적으로 Repository는 @DataJpaTest로 실행하는 걸로 알고있는데, 이럴 경우 어떤식으로 해결을 해야되는 건가요?
- 해결됨실전! Querydsl
chmod 에러
chmod 755 h2.sh 명령을 실행하면 'chmod'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다 라고 나옵니다. 구글링해보니 windows10에서는 chmod 명령어가 지원되지 않는다는 것 같은데 어떻게 해야 할까요?
- 해결됨실전! Querydsl
쿼리 최적화 질문 (N+1문제)
안녕하세요! 강의 복습을 위해서 토이 프로젝트를 하는 중에 N+1 문제를 어떻게 해결해야 할 지 모르겠어서 질문 드립니다. 먼저, 제가 원하는 출력 결과는 아래와 같습니다. ====== 메뉴 정보 ====== id = 101 메뉴 = 후라이드 가격 = 14000 수량 = 2 ====== 옵션 정보 ====== 옵션 = 눈꽃 치즈볼 4개 가격 = 3500 수량 = 2 옵션 = 치즈볼 4개 가격 = 3000 수량 = 2 ====== 메뉴 정보 ====== id = 22 메뉴 = 후라이드 가격 = 14000 수량 = 1 ====== 옵션 정보 ====== 1. 엔티티 [그림 1]. 엔티티 설계 ※ OrderMenu에서 옵션을 선택하지 않으면 OrderMenu, OrderOption 조인 한 뒤에 OrderOption 조회 시 NullPointerException 발생해서 OrderMenu에 양방향 연관관계 추가 [그림 2]. Join 시 <null> 발생 2. 데이터 [그림 3]. 입력한 데이터 아래와 같은 테스트를 작성했을 때 [그림 4]과 같은 N+1 문제가 발생했습니다. @Testpublic void 주문메뉴_주문옵션조회() throws Exception { Long orderId = 100L; List<OrderMenu> fetch1 = queryFactory .select(orderMenu) .from(orderMenu) .where(orderMenu.order.id.eq(orderId)) .fetch(); for (OrderMenu orderMenu : fetch1) { System.out.println("====== 메뉴 정보 ======"); System.out.println("id = " + orderMenu.getId()); System.out.println("메뉴 = " + orderMenu.getMenu().getName()); System.out.println("가격 = " + orderMenu.getMenu().getPrice()); System.out.println("수량 = " + orderMenu.getQuantity()); List<OrderOption> orderOptionList = orderMenu.getOrderOption(); System.out.println("====== 옵션 정보 ======"); for (OrderOption orderOption : orderOptionList) { System.out.println(" 옵션 = " + orderOption.getOption().getName()); System.out.println(" 가격 = " + orderOption.getOption().getPrice()); System.out.println(" 수량 = " + orderOption.getQuantity()); } }} [그림 4] N + 1 문제 발생 위 문제를 해결하기 위해서 fetch join을 사용해서 OrderMenu와 OrderOption을 한 번에 불러왔지만 OrderMenu의 Menu, OrderOption의 Option은 여전히 Lazy loading이 되었습니다. @Testpublic void 주문메뉴_주문옵션조회() throws Exception { Long orderId = 100L; List<OrderMenu> fetch = queryFactory .selectFrom(orderMenu) .distinct() .leftJoin(orderMenu.orderOption, orderOption).fetchJoin() .where(orderMenu.order.id.eq(orderId)) .fetch(); for (OrderMenu orderMenu : fetch) { System.out.println("====== 메뉴 정보 ======"); System.out.println("id = " + orderMenu.getId()); System.out.println("메뉴 = " + orderMenu.getMenu().getName()); System.out.println("가격 = " + orderMenu.getMenu().getPrice()); System.out.println("수량 = " + orderMenu.getQuantity()); List<OrderOption> orderOptionList = orderMenu.getOrderOption(); System.out.println("====== 옵션 정보 ======"); for (OrderOption orderOption : orderOptionList) { System.out.println(" 옵션 = " + orderOption.getOption().getName()); System.out.println(" 가격 = " + orderOption.getOption().getPrice()); System.out.println(" 수량 = " + orderOption.getQuantity()); } }} 출력 내용 select distinct ordermenu0_.order_menu_id as order_me1_7_0_, orderoptio1_.order_option_id as order_op1_8_1_, ordermenu0_.menu_id as menu_id3_7_0_, ordermenu0_.order_id as order_id4_7_0_, ordermenu0_.quantity as quantity2_7_0_, orderoptio1_.option_id as option_i3_8_1_, orderoptio1_.order_menu_id as order_me4_8_1_, orderoptio1_.quantity as quantity2_8_1_, orderoptio1_.order_menu_id as order_me4_8_0__, orderoptio1_.order_option_id as order_op1_8_0__ from order_menu ordermenu0_ left outer join order_option orderoptio1_ on ordermenu0_.order_menu_id=orderoptio1_.order_menu_id where ordermenu0_.order_id=? ====== 메뉴 정보 ====== id = 101 2021-01-27 15:12:12.595 DEBUG 35340 --- [ main] org.hibernate.SQL : select menu0_.menu_id as menu_id1_3_0_, menu0_.created_date as created_2_3_0_, menu0_.last_modified_date as last_mod3_3_0_, menu0_.menu_category_id as menu_cat8_3_0_, menu0_.name as name4_3_0_, menu0_.price as price5_3_0_, menu0_.image_url as image_ur6_3_0_, menu0_.share_url as share_ur7_3_0_, menucatego1_.menu_category_id as menu_cat1_4_1_, menucatego1_.name as name2_4_1_, menucatego1_.restaurant_id as restaura3_4_1_ from menu menu0_ left outer join menu_category menucatego1_ on menu0_.menu_category_id=menucatego1_.menu_category_id where menu0_.menu_id=? 메뉴 = 후라이드 가격 = 14000 수량 = 2 ====== 옵션 정보 ====== 2021-01-27 15:12:12.604 DEBUG 35340 --- [ main] org.hibernate.SQL : select option0_.option_id as option_i1_6_0_, option0_.name as name2_6_0_, option0_.option_category_id as option_c4_6_0_, option0_.price as price3_6_0_ from options option0_ where option0_.option_id=? 옵션 = 눈꽃 치즈볼 4개 가격 = 3500 수량 = 2 2021-01-27 15:12:12.609 DEBUG 35340 --- [ main] org.hibernate.SQL : select option0_.option_id as option_i1_6_0_, option0_.name as name2_6_0_, option0_.option_category_id as option_c4_6_0_, option0_.price as price3_6_0_ from options option0_ where option0_.option_id=? 옵션 = 치즈볼 4개 가격 = 3000 수량 = 2 ====== 메뉴 정보 ====== id = 22 메뉴 = 후라이드 가격 = 14000 수량 = 1 ====== 옵션 정보 ====== OrderMenu와 OrderOption을 조회할 때, 연관된 Menu와 Option을 한 번에 조회하는 방법이 있을까요? 아니면 엔티티 설계를 변경해야 할까요?