월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
Querydsl 잘 되는데, 인텔리제이에서 빨간줄
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]Querydsl이 잘 작동하는데 (QHello 잘 만들어짐, 테스트 잘 성공함)인텔리제이에서 빨간줄이 뜹니다. (아래 캡쳐 참고)어떻게 해결할 수 있을까요?ㅜㅜ 참고로 annotation processors 설정은 이미 enable된 상태입니다.
- 미해결실전! Querydsl
querydsl countQuery
안녕하세요 강의에서와 같이 CountQuery를 적용하였습니다.기대 결과값 : 422개 실제 결과값 : 425개였습니다. sql을 날려서 확인해본 결과 실제 결과값은 leftJoin하여 중복되는 행의 개수만큼 추가되어 있더라구요. 내부적으로 distinct 되어서 422개를 조회하고 싶습니다.혹시 어떻게 해야될까요? 감사합니다. @Override public Page<ReputationPost> findByReputationIdAndUsable(ReputationPostsGetReqDto dto, List<String> keywordList, List<ReputationChannelReqDto> reputationChannelReqDtoList, Pageable pageable, boolean usable) { List<ReputationPost> content = jpaQueryFactory.selectDistinct(reputationPost) .from(reputationPost) .join(reputationPost.post, post).fetchJoin() .leftJoin(postKeyword).on(reputationPost.post.id.eq(postKeyword.post.id)) .leftJoin(memLawkitDoc).on(reputationPost.id.eq(memLawkitDoc.reputationPost.id)) .where( reputationIdEq(dto.getReputationId()), channelIdListIn(reputationChannelReqDtoList), keywordListIn(keywordList), durationEq(dto.getStartDate(), dto.getEndDate()), memLawkitDocStatus(dto.getMemLawkitDocStatusList()) ) .orderBy(getSorting(dto.getSortOption())) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); JPAQuery<Long> countQuery = jpaQueryFactory.selectDistinct(reputationPost.count()) .from(reputationPost) .join(reputationPost.post, post) .leftJoin(postKeyword).on(reputationPost.post.id.eq(postKeyword.post.id)) .leftJoin(memLawkitDoc).on(reputationPost.id.eq(memLawkitDoc.reputationPost.id)) .where( reputationIdEq(dto.getReputationId()), channelIdListIn(reputationChannelReqDtoList), keywordListIn(keywordList), durationEq(dto.getStartDate(), dto.getEndDate()), memLawkitDocStatus(dto.getMemLawkitDocStatusList()) ); return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); }
- 미해결실전! Querydsl
질문드립니다
@Test public void paging2() { QueryResults queryResults = queryFactory .selectFrom(member) .orderBy(member.username.desc()) .offset(1) .limit(2) .fetchResults(); assertThat(queryResults.getTotal()).isEqualTo(4); assertThat(queryResults.getLimit()).isEqualTo(2); assertThat(queryResults.getOffset()).isEqualTo(1); assertThat(queryResults.getResults().size()).isEqualTo(2); } 여기코드에서 queryResults 의 size 가 2인이유는 4/2인건가요? 3/2인건가요? offset이 1부터 시작인데 1부터 시작해야되는건지 0부터 시작해야되는건지 잘모르겠습니다..1부터 시작인데 왜 전체 개수가 4개인지도 의문이고 참고로 member에는 4개가 저장되어있습니다.
- 미해결실전! Querydsl
EntityManager와 멀티쓰레드
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]EntityManager가 멀티스레드 상황에서 안전하게 작성되있다고 하셨는데 그걸 확인하기 위해서는 어느 부분을 확인하면 될까요? 제가 queryFactory와 비슷하게 작동하는 외산 패키지를 쓰고 있는데 그것도 멀티스레드에 안전한지 확인하고 싶어서 질문 남깁니다.
- 미해결실전! Querydsl
상속 구조 내에서 Querydsl로 특정 타입의 엔티티에만 조인
안녕하세요, 질문이 있어서 글 남기게 되었습니다.이런식으로 지점(branch)명에 맞는 공간(space)중 미팅룸 리스트를 보여주고해당 미팅룸의 해당 날짜의 예약들도 보여주는 기능을 구현하고자 @Override public List<Reservation> findReservationListByDateAndBranchName(LocalDateTime startDatetime, LocalDateTime endDateTime, String branchName) { return queryFactory .select(reservation) .from(reservation) .join(reservation.space, space).fetchJoin() .join(space.branch, branch) .where(branch.branchName.eq(branchName), reservation.reservationStartDateTime.between(startDatetime, endDateTime), space.dtype.eq("MeetingRoom") ) .fetch(); }이런 코드를 작성하였는데 아래와 같은 연관관계 때문에Reservation Entity@Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "reservation") public class Reservation extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "reservation_id") private Long reservationId; @Column(name = "reservation_start_date_time") private LocalDateTime reservationStartDateTime; @Column(name = "reservation_end_date_time") private LocalDateTime reservationEndDateTime; @OneToMany(mappedBy = "reservation") private List<MemberReservation> memberReservations = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "space_id") private Space space; }Space Entity@Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "space") @DiscriminatorColumn public abstract class Space { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "space_id") private Long spaceId; @NotNull @Column(name = "space_name") private String spaceName; @NotNull @Column(name = "space_floor") private int spaceFloor; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "branch_id") private Branch branch; @OneToMany(mappedBy = "space") private List<Reservation> reservations = new ArrayList<>(); @NotNull @Column(name = "dtype", insertable = false, updatable = false) private String dtype; }Space를 상속받는 FocusDesk, MeetingRoom, RechargingRoom@Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "focus_desk") public class FocusDesk extends Space { //추후에 해당 엔티티에 맞는 필드들 추가 } @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "meeting_room") public class MeetingRoom extends Space { @Column(name = "meeting_room_capacity") @Positive private int meetingRoomCapacity; } @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "recharging_room") public class RechargingRoom extends Space { //추후에 해당 엔티티에 맞는 필드들 추가 } select r1_0.reservation_id, r1_0.created_date, r1_0.last_modified_date, r1_0.reservation_end_date_time, r1_0.reservation_start_date_time, s1_0.space_id, s1_0.dtype, s1_0.branch_id, s1_0.space_floor, s1_0.space_name, s1_2.meeting_room_capacity from reservation r1_0 join (space s1_0 left join focus_desk s1_1 on s1_0.space_id=s1_1.space_id left join meeting_room s1_2 on s1_0.space_id=s1_2.space_id left join recharging_room s1_3 on s1_0.space_id=s1_3.space_id) on s1_0.space_id=r1_0.space_id join branch b1_0 on b1_0.branch_id=s1_0.branch_id where b1_0.branch_name=? and r1_0.reservation_start_date_time between ? and ? and s1_0.dtype=?이런 쿼리가 나가게 됩니다.처음에는 dtype 없이 MeetingRoom 만 join 하고 싶었지만reservation.meetingRoom 이불가능하여(reservation은 space랑 매핑 되어있으니까)불가능하여 이방법 밖에는 떠오르지 않았습니다. 문제는 위의 쿼리처럼 쓸모없는 테이블들을 강제로 조인한 후에 다시 where절의 dtype으로 구분을 해야한다는 것입니다. @Query("SELECT new com.example.sabujak.reservation.dto.ReservationQueryDto(r.reservationStartDateTime, r.reservationEndDateTime, s.spaceId, s.spaceFloor, s.spaceName, m.meetingRoomCapacity) " + "FROM Reservation r " + "JOIN r.space s " + "JOIN MeetingRoom m ON m.spaceId = s.spaceId " + "JOIN s.branch b " + "WHERE b.branchName = :branchName " + "AND r.reservationStartDateTime BETWEEN :startDateTime AND :endDateTime")이런식의 jpql로는 해결이 가능하지만추후에 정렬조건을 동적으로 받아야 하기에 querydsl을 사용해서 최대한 좋은 방향으로 사용하고 싶은데어떻게 해야할지 잘 모르겠습니다
- 미해결실전! Querydsl
QueryDsl의 ON절에 대해 질문드립니다.
SQL의 ON절과 QueryDsl의 ON절 간에 차이가 있어보여 질문드립니다. SQL의 ON절에서는 테이블과 테이블 간에 어떤 컬럼을 기준으로 조인될 것인가를 명시하는 기능을 하는데 비해, QueryDsl에서는 join메서드가 그 기능을 포함하고 on메서드가 마치 sql의 where절의 역할을 하는 것(그렇기 때문에 QueryDsl에서는 SQL과 달리 on 메서드와 where 메서드를 함께 사용할 수 없음)으로 보이는데 맞을까요?
- 미해결실전! Querydsl
테스트 오류
[질문 내용]https://drive.google.com/file/d/1z8O0dwyDnjTmm-OtFu6CcHwTW6sXSxlV/view?usp=sharing 강의 따라하다가 clean 하고 build를 다시 했는데 빌드시 테스트에 오류나고 테스트실행시 모두 오류떠서 돌아가지 않습니다..ㅜㅜ !
- 미해결실전! Querydsl
@Transactional 시 @Rollback(value = false)와 @Commit의 차이
@Test @Transactional @Rollback(value = false) void testMember() { // given Member member = new Member(); ..... }@Test @Transactional @Commit void testMember() { // given Member member = new Member(); ..... }JUnit에서 테스트 할 때 @Transactional이 붙어있으면 자동으로 롤백되기 때문에 기본 동작을 방지하기 위해(테스트 후에 persist한 데이터를 확인할 수 있도록 하기 위해) @Rollback(value = false)를 사용한다고 알고있습니다.그렇다면 @Rollback(value = false) 대신 @Commit을 사용해도 같다고 봐도 될까요?
- 해결됨실전! Querydsl
서브 쿼리기 때문에 이름이 없다고 하신 이유에 대해 질문드립니다.
프로젝션과 결과 반환 - DTO 조회 강의의 15:23에서 '서브쿼리이기 때문에 이름이 없다'고 하신 부분이 이해가 가지 않아서 추가 설명해주시면 감사하겠습니다 🙂
- 미해결실전! Querydsl
환결설정 질문입니다.
https://www.inflearn.com/questions/979214/hello-unittest%EC%97%90%EB%9F%AC 와 같은에러가 납니다. 코드도 같아요. 현재 프로젝트 환경설정 부분중이구요. 그런데 답변에서 시퀀스를 생성하라는데 어떻게 하는건가요? 강의 교재에서도 HELLO_SEQ 이런단어는 없고 제 인텔리제이에도 이런단어는 없습니다.
- 미해결실전! Querydsl
Querydsl 설정과 검증 질문있습니다.
Querydsl 설정과 검증 12분에서 QHello파일에서 public static final QHello hello=new QHello("hello"); 이렇게 있는데Hello resutlt=query.selectFrom(qhello).fatchOne(); 이코드에서 어떻게 result값이 Hello@10909가나오는건가요?qhello이란 단어가 QHello파일에서 없어요.
- 미해결실전! Querydsl
콘솔창에서 로그가 가로로만 나오고 있어요
[질문 내용]여기에 질문 내용을 남겨주세요. 혹시 인텔리 제이에서 쿼리의 결과 들이 가로로 줄줄이 지어서 나오는데 보기가 힘들어서 혹시 정렬하는 방법이 따로 있나요?
- 미해결실전! Querydsl
PDF 제안: -AND 조건을 콤마로 처리-로 수정해야 할 것 같은데 확인 부탁드립니다!
3.기본문법 pdf 파일에서 'AND 조건을 파라미터로 처리' 섹션이 있습니다. 페이지로는 6페이지 정도 되는 것 같습니다. 이 부분에서 AND를 이용한 메서드 체이닝 방식과 함께 predicate를 이용해 콤마로 AND조건을 소개해주시고 있습니다.타이틀을 'AND 조건을 콤마로 처리'로 수정해야 할 것 같은데 한번 확인 부탁드립니다!
- 미해결실전! Querydsl
@Transactional + @Commit의 의미
비슷한 질문이 올라왔는데 질문의 의도와 답변 내용이 불일치하는 것 같아 다시 한번 질문드리겠습니다.@Transactional(readonly=false)는 테스트 후에 자동으로 롤백되는 기본 동작을 방지하기 위해(즉 커밋되도록 하기 위해) 사용됩니다. 이전 강의에서 JUnit 테스트 시 데이터를 변경한 결과를 DB에서 확인하고자 할 때 이 설정을 사용한 것으로 기억합니다. 질문@Transactional은 기본적으로 rollback=true가 디폴트이므로 @Transactional + @Commit은 @Transactional(readonly=false) 같은 의미라고 볼 수 있을까요?
- 해결됨실전! Querydsl
lombok의 @ToString이 가지는 이점
lombok의 @ToString으로 설정해주는 것보다 인텔리제이가 단축키로 toString을 오버라이드 하는 것이 더 간단해보이는데 @ToString이 가지는 이점이 있나요?
- 미해결실전! Querydsl
contextLoads() 테스트 오류 질문드립니다.
@SpringBootTest class QuerydslApplicationTests { @Autowired EntityManager em; @Test void contextLoads() { Hello hello = new Hello(); em.persist(hello); JPAQueryFactory query = new JPAQueryFactory(em); QHello qHello = new QHello("h"); Hello result = query .selectFrom(qHello) .fetchOne(); assertThat(result).isEqualTo(hello); } }강사께서 진행하신 테스트를 똑같이 따라했는데 계속해서 TransactionRequiredException이 발생했습니다. 결국 @Transactional을 붙여주니 테스트가 정상적으로 수행됐는데요, 강의에서는 @Transactional이 없이도 잘 동작했는데 왜 저는 그렇지 않은 이유가 무엇일까요? 참고로 Spring Boot 3.2.5 최신 버전 사용중입니다.
- 미해결실전! Querydsl
application.yml 분리 이유에 대해 궁금합니다.
영한님이 말하시기에 자기는 application-local, dev, 운영 이렇게 나누신다고 하셨습니다. 당연히 나누어야 하는 것에 동의합니다. 하지만 왜 IntelliJ 내에서도 나누어야 하는지 궁금합니다 . 그냥 저는 local yml 만 인텔리제이에 두고 dev yml 은 따로 팀 공동 노션에 보관하는데 그걸 intelliJ 내에서 돌리는 일이 거의 없었던 것 같습니다. 왜 intelli J 내에서 따로 운영 yml 이나 이런 걸 보관하는 건가요??
- 미해결실전! Querydsl
롬복 @AllArgsConstuctor 는 왜 안될까요?
@Data @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor public class MemberDto { private String username; private int age; /* public MemberDto(String username,int age){ this.username = username; this. age =age; }*/ } 롬복 @All Args 가 아래 주석처리된 생성자 코드를 대체한다고 알 고 있는데 빨간줄이 나오는 이유가 무엇일까요? 그냥 All Args 빼고 직접 생성자 입력하면(주석해제) 하면 잘됩니당.
- 미해결실전! Querydsl
페치조인 관련해서 질문있습
@Test public void fetchJoinNo() throws Exception{ em.flush(); em.clear(); /*Member findMember = queryFactory .selectFrom(member) .where(member.username.eq("member1")) .fetchOne();*/ Tuple tuple= queryFactory .select(member,team) .from(member) .where(member.username.eq("member1")) .fetchOne(); String qlString= "select m,m.team from Member m where m.username=:username"; Tuple tuple1 = (Tuple) em.createQuery(qlString, Tuple.class).setParameter("username","member1") .getResultList(); boolean loaded = emf.getPersistenceUnitUtil().isLoaded(tuple.get(team)); assertThat(loaded).as("페치 조인 적용").isTrue(); } 위 코드는 위 코드에서 tuple 을 이용해서 ,member 와 team 을 함꼐 조회해 보았을 때 team 이 영속화 되는지 실험한 것입니다. 아래 코드입니다. queryFactory .select(member,team) .from(member) .where(member.username.eq("member1")) .fetchOne(); 원래 fetchJoin() 을 안붙여서 안될 것이라고 생각했습니다만 의외로 되가지고 뭐지 ? 했습니다. 원래 되는 것인가요?? 그러면 원래 이게 의미하는 JPQL 인 select member1, team from Member member1 where member1.username = ?1 를 직접 작성하면 @Query("select m, m.team from Member m wherer m.username=:username)뭐 이런식으로 해도 fetch join 이 된다는 얘기 아닌가요?
- 미해결실전! Querydsl
count 쿼리의 성능 관련 질문
페이징 부분에서 참고 부분에서 실무에서 페이징 쿼리를 작성시 데이터를 조회하는 쿼리는 여러 테이블을 조인해야 하지만 count 쿼리는 조인이 필요없는 경우도 있다 . 에 대한 구체적인 실무, 혹은 실제 예를 알고싶습니다,