30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨실전! Querydsl
QueryDSL 테스트 관련해 질문드립니다
안녕하세요 영한님! compileQueryDSL로 생성된 Qclass들은 github에 올리지 말라고 하셔서 그대로 적용해 사용 중입니다. 제가 Qclass를 사용하는 Test 코드를 작성하고 로컬에서는 Qclass가 프로젝트 내에 존재하니 문제 없이 실행되지만, CI / CD 연습을 위해 github push, pull request 기준으로 깃 레포에서 코드를 받아와 빌드를 하는데 Qclass가 없어서 test 코드가 터져 빌드가 실패합니다. 1. Qclass를 노출하지 않는 이런 경우에는 Test 코드 작성을 어떻게 해야할까요? 2. Test 코드에 @Profile 을 local이 아닌 것을 줘서 수행되지 않도록 하는 것이 최선일까요?
- 미해결실전! Querydsl
N+1 현상
안녕하세요 영한님 잘보고있습니다. 감사합니다 질문이 하나 있습니다. public List<MemberTeamDto> searchByBuilder(MemberSearchCondition condition){ BooleanBuilder builder = new BooleanBuilder(); if(StringUtils.hasText(condition.getUsername())){ builder.and(member.username.eq(condition.getUsername())); } if(StringUtils.hasText(condition.getTeamName())){ builder.and(team.name.eq(condition.getTeamName())); } if(condition.getAgeGoe() != null){ builder.and(member.age.goe(condition.getAgeGoe())); } if(condition.getAgeLoe() != null){ builder.and(member.age.loe(condition.getAgeLoe())); } return queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName") )) .from(member) .leftJoin(member.team, team) .where(builder) .fetch(); } //페치조인 미 적용 테스트를 해보면 @Test public void searchTest(){ Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); em.persist(teamA); em.persist(teamB); Member member1 = new Member("member1", 10, teamA); Member member2 = new Member("member2", 20, teamA); Member member3 = new Member("member3", 30, teamB); Member member4 = new Member("member4" ,40, teamB); em.persist(member1); em.persist(member2); em.persist(member3); em.persist(member4); MemberSearchCondition condition = new MemberSearchCondition(); condition.setAgeGoe(35); condition.setAgeLoe(40); condition.setTeamName("teamB"); List<MemberTeamDto> result = memberJpaRepository.searchByBuilder(condition); assertThat(result).extracting("username").containsExactly("member4"); } N+1 같은 현상이 일어나지 않습니다. 페치 조인을 사용하지 않았는데 이유가 있을까요 ?
- 미해결실전! Querydsl
강의듣는중에 테스트에서 갑자기 모든 테스트가 null point exception 이 뜹니다..
안녕하세요 영한팀장님. 강의 너무 잘듣고있습니다. 갑작스럽게 어제까지 잘돌아가던 테스트가 오늘 '집합'부분 테스트를 만들고나서 (aggregation()메소드) queryFactory 부분에서 nullpointexception이 납니다. 혹시 QClass가 이상하게 되었나 싶어서 clean하여 다시 컴파일하고 실행해도 동일합니다. 그 전에 잘되었던 기존 테스트들도 줄줄이 똑같은 예외를 뱉으며 테스트에 실패합니다.. 이유가 무엇일까요ㅠ 2시간동안 강의못듣고 끙끙 헤매다가 처음으로 질문을 올려봅니다ㅠㅠㅠ https://drive.google.com/file/d/1ad-mUAI4eRBYuNgKk72mF-MKnpNg2Bp8/view?usp=sharing 소스 코드 공유합니다!! 또한, symbol을 찾지 못하는 예외도 같이 떠서 구글링중에 인텔리제이 설정도 만져보았으나.. 해결되지 않습니다 ㅠㅠ
- 미해결실전! Querydsl
벌크연산시, 소수점은 반영이 안되나요?
안녕하세요 벌크연산에서 multiply나 devide를 사용하면서 전체 임금 30프로 인상이나 삭감등의 경우를 연습해보고있는데요, queryFactory .update(member) .set(member.salary, member.salary.multiply(1.3)) .execute(); 코드가 다음과 같은 경우, update member set salary=salary*1; 이런 쿼리가 나가는 것을 확인하였고, multiply와 devide함수가 받는 파라미터 정보를 보니 NumberExpression<Integer> 이렇게 되어있는데, 아마 받는 파라미터가 Integer로 정의되어있어서 소숫점은 버려지는것이 아닌가 싶습니다. 이런경우 받는 파라미터를 Double형으로 바꿔주면 해결이 될것 같은데, 어떤식으로 바꿀수가 있을까요? 아니면 다른 해결방법이 있을까요?
- 미해결실전! Querydsl
크로스조인
안녕하세요 영한님 강의 항상 잘 듣고있습니다. 실무에서도 cross join을 사용 하는 경우가 있을까요? 데이터 뻥튀기가 어마어마 한거같아서 질문드립니다
- 미해결실전! Querydsl
안녕하세요 Build and run 질문입니다
안녕하세요! 선생님 강의를 여러개 듣고 나서 개인 프로젝트를 하다가 로그인 & crud 정도만 조금 구현 해놓고 Querydsl을 듣고 있었습니다. 강의에서 5:34 에 나오는 Build and run using을 Gradle -> IntelliJ IDEA로 바꾸는 과정을 보면서 제 개인 프로젝트에 적용을 하지 않은것을 깨달아 그것을 변경하였는데 로그인 과정에서 전에 발생하지 않던 아래의 에러가 나는겁니다. Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: For queries with named parameters you need to use provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters.; 구글링을 통해서 아래와 같이 레포지토리에 있는 jpql 메소드의 파라미터에 @Param을 추가해서 에러는 해결했습니다. 여기서 궁금한것은 왜 Gradle 에서 IntelliJ IDEA로 바꿨다해서 에러가 났을까? 입니다. 감사합니다
- 미해결실전! Querydsl
predicate 보다 booleanExpression을 선호하는 이유가 뭔가요?
booleanExpression은 and, or 을 조합해서 새로운 BooleanExpression을 만드는것과 같이 메서드를 재사용할 수 있고 null을 받으면 무시해서 npe를 방지할 수 있다라고 하는 글을 봤습니다. 근데 predicate는 and, or을 조합하지 못한다는게 이해가 안됩니다. 정확히 어떤 상황을 말하는 것인지 여쭤봐도 될까요?
- 미해결실전! Querydsl
프로젝션 반환 타입의 레이어가 고민됩니다
프로젝션 쿼리에서 DTO를 사용하게 되면, Domain-Application-UI 모든 레이어에 의존성이 생기게 되는데요.. 그래서 DTO가 아니라 VO로 봐도 될지 고민 됩니다. 영한님의 의견과 실무에서 반환타입을 어떻게 사용하고 계신지 궁금합니다!!
- 미해결실전! Querydsl
그룹함수 질문이 있습니다.
안녕하세요. 결론부터 말씀드리자면 sum(time) 을 하는 방법을 여쭤보고 싶습니다. db는 mysql 이고 데이터 타입은 time 입니다. sum을 사용할려고 하다보니 일반 쿼리로 작성을 할때는 sum(time)으로 하면 정상으로 결과가 나오는데 QueryDsl에서 작성을 할려고 하다보니 time.sum이 되지 않더라고요. Expressions.timeTemplate이 라는걸 사용했을때는 생성된 쿼리를 직접 돌리면 원하는 결과는 나오는데 queryDsl에서는 오류가 나고 있구요. time -> millisecond, second 로 바꾸고 sum을 할려고 했는데 해당 함수는 그 위치의 값을 가지고 오더라구요. 딱히 찾아봐도 방법을 모르겠어서 문의 드립니다.
- 미해결실전! Querydsl
select(member, team).from(member)
select(member, team).from(member) 이 부분이 이해가 너무 안되는데요 ㅠㅠ 이전 강의에서 selectFrom(member)를 했을 때는 멤버의 모든 필드를 조회해서 보여준다고 생각했습니다. 만약에 select(member, team)을 하게 되면, member필드와 team필드 모두 다 붙여서 보여주게 되나요? 가령, member테이블에는 id, username, team테이블에는 id,teamname이 있다면 id | username | id | teamname 이런식으로요..! 쿼리로 select * from member, team과 같은건지 궁금합니다 ! 그리고 .leftJoin(member.team, team)에서 member.team은 어떤걸 의미하는지도요..! ㅠㅠ 제가 join을 공부했을 때는 select * from member LEFT JOIN team ON ~ 이런 쿼리가 있을 때, 왼쪽(member 테이블)을 기준으로 오른쪽 테이블을 붙여서 출력해라! 이런 식으로 이해를 했는데요, 쿼리dsl에서는 어떻게 되는지 이미지화가 안돼요 ㅠㅠ혹시나 제 질문에 도움이 될까 싶어서 https://www.youtube.com/watch?v=pJqBR2TNe24 이 영상으로 공부했다는 점 알려드립니다..! 프로젝트 중이라 급히 사용해야 하는데 아직 이해가 안되서 큰일이에요 ㅠㅠㅠ 가능하면 상세한 답변 부탁드립니다! 감사합니다 !!
- 해결됨실전! Querydsl
Projection 사용 불가 시 One To Many 엔티티 fetch 시 cartesian product없이 n + 1 문제 해결하기
대략적 엔티티 구조 public class Level { ... @OneToMany(mappedBy = "level", cascade = CascadeType.ALL) private List<LevelCreator> levelCreators = new ArrayList<>(); } public class LevelCreator { ... @ManyToOne(fetch = LAZY) @JoinColumn(name = "level_id") @NotNull private Level level; } 위와같이 Level과 LevelCreator가 1:N으로 설계된 상태에서 QueryDSL을 사용하여 Level을 levelCreators가 전부 채워진 상태로 cartesian product와 n + 1 문제 없이 fetch하는 방법이 무엇인가요? 현재의 경우는 cartesian product가 발생하더라도 단순히 1개의 쿼리로 처리하는 것이 더 효율적일 수 있다고 생각하고 있습니다만 추후 1:N을 2개 이상 fetch join해야할 경우가 나왔을 때 이를 풀어나가기 위해 질문합니다. Dirty Checking을 사용해 자동으로 업데이트를 수행하기 위해 Dto등을 사용하지 않아 Projection사용이 곤란한 상태입니다. 만약 Projection을 사용하여서 cartesian product와 n + 1을 전부 피하면서 Dirty Checking도 가능한 방법이 있다면 알려주시면 감사하겠습니다. 현재 시도해본 것. 1. queryFactory.selectFrom(level).fetch(); // n+1 2. queryFactory.selectFrom(level) .join(level.levelCreators).fetchJoin().fetch(); // cartesian product 3. List<Level> levelList = queryFactory.selectFrom(level).fetch(); Map<Long, List<LevelCreator>> levelCreatorMap = queryFactory.selectFrom(levelCreator) .innerJoin(levelCreator.level, level) .fetchJoin().fetch().stream() .collect(Collectors.groupingBy(lc -> lc.getLevel().getId())); levelList.forEach(levelEntity -> { levelEntity.getLevelCreators().clear(); List<LevelCreator> levelCreatorList = levelCreatorMap.get(levelEntity.getId()); if (levelCreatorList != null) levelEntity.getLevelCreators().addAll(levelCreatorList); }); // n + 1 해결방법을 찾았습니다. Test환경에서 따로 application파일을 생성해야 할 경우 해당 파일에도 default_batch_fetch_size를 설정해주어야 했습니다. List<Level> results = queryFactory.selectFrom(level) .fetch(); results.stream().map(Level::getLevelCreators) .forEach(Hibernate::initialize); return results; 또한 해당 코드를 사용해 Hibernate initialize를 호출함으로써 batch size를 활용한 n+1문제 해결이 가능했습니다. 참고함 : https://blog.leocat.kr/notes/2020/01/13/querydsl-duplication-problem-on-fetchjoin-with-onetomany
- 미해결실전! Querydsl
사용자 정의 repository의 implementation class들을 더 작은 클래스들로 쪼개는 방법
만약 예를 들어, repository: WorkRepository Custom Repository interface: WorkRepositoryCustom Custom Repository interface Implementation: WorkRepositoryImpl 정도로 구성되 있을 경우, WorkRepositoryImpl (또는 WorkRepositoryCustom interface)가 너무 커져서 별도의 작은 클래스로 쪼개려고 시도중인데요, 추천하실 만한 방법이 있을까요?
- 미해결실전! Querydsl
querydsl random select관련
안녕하세요 querydsl을 사용하여 이것저것 해보다가, 랜덤으로 orderby해서 값을 가져오는 경우엔 어떻게 해야할지 궁금합니다 jpa나 jpql, querydsl을 사용하여 random select를 구현할 순 없을까요?? 참고로 DB는 MariaDB입니다!
- 미해결실전! Querydsl
querydsl 설정 문의
안녕하세요 강사님 다름이아니라 querydsl 설정하는데 있어서 문제가 있어서 이렇게 질문 남깁니다. error: cannot find symbol public class QBook extends EntityPathBase<Book> { ^ symbol: class Book 이런식으로 Book Entity의 QBook을 만들어서 run을 하면 위 같은 Book을 찾지 못한다는 에러가 발생합니다 어떻게 해결해야 할까요 ㅠㅠ
- 미해결실전! Querydsl
연관관계 편의 메소드에서 질문 있습니다!
안녕하세요 강의 수강 중 연관관계 편의 메소드에서 궁금한 점이 있어서 질문 드립니다. Members.java @Entity@Getter @Setter@NoArgsConstructor(access = AccessLevel.PROTECTED)@ToString(of = {"id", "username", "age"}) public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String username; private int age; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; public Member(String username) { this(username, 0); } public Member(String username, int age) { this(username, age, null); } public Member(String username, int age, Team team) { this.username = username; this.age = age; if (team != null) { changeTeam(team); } } public void changeTeam(Team team) { this.team = team; team.getMembers().add(this); }} public void changeTeam(Team team) { this.team = team; team.getMembers().add(this);} 위의 메소드에서 만약 인자로 넘어온 team이 teamA라면 team.getMembers()를 하면 teamA에 속해 있는 member들이 쭉 뽑아지는거 아닌가요? 맞다면 이 getMembers()는 어디에 있는 member들을 뽑아오는 건가요? 뭔가 머리 속에 상상이 안돼서 그런데 구체적인 예시를 들어주시면 감사하겠습니닷!
- 미해결실전! Querydsl
간단한 질문이 있어 질문 남깁니다.
제가 이렇게 rollup 을 사용한 querydsl 을 만들고 싶어 검색을 해봤지만 mysql 에서 지원해는 mysqlquery 의 rollup 만 발견을 했습니다-> 제가 mssql 을 쓰고어서혹시 querydsl 에서 rollup 이나 cube 같은 기능을 지원을 해주는지 궁금합니다 출처 : https://myjamong.tistory.com/191
- 미해결실전! Querydsl
EntityManager Thread safe관련 문의드립니다.
안녕하세요 김영한 강사님 강의듣다 처음 질문올립니다~~! EntityManager의 Thread-Safe관련 문의드립니다. 영한님 책 83Page에서 엔티티 매니저는 스레드간 공유하거나 재사용하면 안된다 라고 설명이 되어있는데 이게 스레드 안전하지 않다라는 내용과는 다른건가요? 전 그부분보고 지금까지 엔티티매니저는 스레드안전하지 않아서 멀티 스레드에서 사용하려면 동기화를 해줘야한다고 생각했었는데 이번 강의(순수JPA리포지토리와 Querydsl)에서 스레드 안전하다고 말씀하셔서, 궁금합니다! 아니면 본래 엔티티매니저는 스레드안전하지 않지만 스프링에서 스레드 안전하게 사용하도록 처리해주고 있는건가요?(강의에서 스프링이 Proxy를 사용한다고 말씀해주시긴 해서 혹시 이거랑 관련있는지 궁금합니다) 항상 좋은강의 너무 잘 듣고있습니다. 감사합니다~~!
- 미해결실전! Querydsl
querydsl gradle 의존성 충돌
안녕하세요, 영한님 JPA 강의 잘 듣고있습니다. 다름이 아니라, 강의에 나온 query dsl의존성 설정하엿는데 org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':compileClasspath'. ... Caused by: org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.conflicts.VersionConflictException: A conflict was found between the following modules: - org.javassist:javassist:3.24.0-GA - org.javassist:javassist:3.18.2-GA A conflict was found between the following modules: - com.google.guava:guava:18.0 - com.google.guava:guava:15.0 Run with: --scan or :dependencyInsight --configuration compileClasspath --dependency org.javassist:javassist 위와 같은 에러가 생깁니다. guava와 의존성이 충돌하는것 같은데.. 해결할 수 있는 방법이 있을까요?
- 미해결실전! Querydsl
안녕하세요. 질문드립니다.
java.lang.IllegalArgumentException: Could not locate ordinal parameter [1], expecting one of [] 이와 같은 익셉션이 발생합니다. 실행 테스트 코드 입니다. package study.querydsl.repository;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.transaction.annotation.Transactional;import study.querydsl.entity.Member;import javax.persistence.EntityManager;import java.util.List;import static org.assertj.core.api.Assertions.assertThat;@SpringBootTest@Transactionalclass MemberRepositoryTest { @Autowired EntityManager em; @Autowired MemberRepository memberRepository; @Test public void basicTest() { Member member = new Member("member1", 10); memberRepository.save(member); Member findMember = memberRepository.findById(member.getId()).get(); assertThat(findMember).isEqualTo(member); List<Member> result1 = memberRepository.findAll(); assertThat(result1).containsExactly(member); List<Member> result2 = memberRepository.findByUsername("member1"); assertThat(result2).containsExactly(member); }} 에러는 List<Member> result2 = memberRepository.findByUsername("member1"); 여기서 발생합니다. git 주소 입니다. https://github.com/aispark/querydsl
- 해결됨실전! Querydsl
객체설계에 대해서 질문이 있습니다.
안녕하세요. 김영한 강사님. 강사님이 올려주신 강의를 잘 듣고 있습니다. 궁금한 부분은 JPA를 사용하고 있는 현업에서는 어떻게 설계하며, 개발을 진행하는지입니다. 우선 제 상황을 간단하게 말씀드리면 업무요건을 확인하면서 아래의 단계로 설계를 진행합니다. 1. 개념데이터 모델링 - 주 목적은 업무요건에 맞춰서 엔터티가 잘 도출되었는지 확인합니다. 2. 논리데이터 모델링 - 주제영역 , 엔터티 정의, 엔터티관계 정의(1:1, 1:N), 속성정의(식별자도출), 역정규화 등등 - 메타데이터(표준단어, 표준용어, 도메인,유효값) 한글(영문)명 생성 3. 물리데이터 모델링 - 논리데이터 모델링을 기준으로 물리데이터 생성합니다. 위 단계처럼 계속적으로 업무요건에 맞게 논리데티터 모델링을 진행하고, 최종적으로 물리데이터 모델링을 진행후 에 개발을 진행합니다. 질문-1) 궁금한건 JPA DDD 기반으로 설계를 하는경우에도 위 단계처럼 엔터티 설계 후 객체(Entity)를 테이블 기준으로 생성하는지요? 아니면 객체와 테이블을 나누어서 영역별로 설계를 진행하는지요? 객체와 테이블간의 설계 순서가 있는지 궁금합니다. 질문-2) 만약 위 질문-1)처럼 테이블 설계 후 객체(Entity) 설계를 진행하는경우 객체의 필드를 테이블기준으로 컬럼매핑한다면 맵핑관계에서 객체필드의 속성들을 테이블속성에 위임하는지요? 즉, 물리테이블 생성 시 컬럼사이즈, not null, default, unique index 정의 해놓고 추가적으로 객체에도 컬럼 어노테이션으로 추가적으로 설정을 하는지요. 아니면 테이블 속성에 위임을 하는지 궁금합니다. 질문-3) 객체별 식별자는 @ID Long ID 를 정의해서 수업을 진행하셨는데 보통 pk는 어떤 규칙으로 생성하는지 궁금합니다. - 어떤 교재에서는 독립엔터티인경우 인조키로 생성하여 종속 혹은 교차엔터티는 부모의 식별자를 상속(pk) or 비상속(fk)받거나, 하위 엔터티와의 연관관계가 깊어지면 연결관계를 끊고 인조키를 생성한다고 합니다. - 근데 또 어떤분들은 인조키만으로도 충분하다고 하시면서 모든 테이블(독립/교차/종속 전체)들을 모두 인조키로만 생성하여 진행한다고도 합니다. 질문-4) JPA 영속성 컨텍스트(SQL 저장소,1차캐시)는 지연 및 변경을 이용하여 SQL를 직접 사용하지 않고 Jpql, Flush, Transaction 등 특정 이벤트가 발생하면 jpa가 쿼리를 직접 수행하는걸로 이했습니다. 정말 개발자에게는 등록/수정/조회/삭제 등 쿼리 작성하지 않고 비지니스 로직처리에 집중한다고 하는데 좋은 기술인거 같습니다. 만약 영속성 컨텍스트를 사용하여 특정 객체를 조회하면 추가적으로 동일 객체를 조회하게 된다면 영속성 컨텍스트에 있는 객체가 조회된다고 이해하였습니다. (참조값동일) 하지만 만약 누군가가 이미 동일 객체를 변경하여 오라클 버퍼캐쉬 및 디스크까지 저장된 상태라면 어떻게 되는지요? 트랜잭션 격리성이 "Non-Repeatable Rad" 인지요? 영속성 컨텍스트가 변경감지를 통해서 동일객체가 변경되었다는걸 알고 db에서 재조회를 한 이후에 영속성컨텍스트에 재적재를 하는지 잘 이해가 되지 않아서 질문드립니다. (참고 16.1.1 트랜잭션과 격리수준) 감사합니다.