2022-08-01 개발일지

컴클로딩·2022년 8월 4일
0
post-thumbnail

📂 Error List

1. Scalar subquery contains more than one row; SQL statement:

  • 발생한 오류
    • Scalar subquery contains more than one row; SQL statement:
    • select room0_.room_id as col_0_0_,
      		room0_.title as col_1_0_,
            	room0_.price as col_2_0_,
            	(select image1_.img_url from image
                image1_ where room0_.room_id=image1_.room_id)as col_3_0_
      from room room0_
      where room0_.category=?
      limit ?
      offset ? [90053-200]
    • 위 SQL문은 QueryDsl을 통해 만들어진 SQL문이다. 아래 오류 발생한 코드에서 보면 서브쿼리 안에 limit(1)을 넣었지만 실제 서브쿼리 안에는 limit에 대한 내용이 적용되지 않았고 where절 밑에 적용되어있다...
  • 오류가 발생한 코드
    @Override
    public Slice<GetRoomsResponseDto> findAllByCategoryOrderByCreatedAt(String category, Pageable pageable, Long userId) {
        List<GetRoomsResponseDto> returnRoom = queryFactory.select(Projections.fields(
                        GetRoomsResponseDto.class,
                        room.id,
                        room.title,
                        room.price,
                        // imgUrl 1개만 가져오기  room.imageList.get(0) 오류남
                        ExpressionUtils.as(
                                JPAExpressions
                                        .select(image.imgUrl)
                                        .from(image)
                                        .limit(1)
                                        .where(room.id.eq(image.room.id))
                                        ,"imgUrl"
                        )
                    )
                ))
                .from(room)
                .where(room.category.eq(category))
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
        return new SliceImpl<>(returnRoom, pageable, returnRoom.iterator().hasNext());
    }
  • 오류 발생 이유
    • QueryDsl에서 서브쿼리안에 limit가 먹히질 않아서 2개의 row를 가져서 Scalar subquery contains more than one row; SQL statement:오류가 났음. 구글링을 해보니 아래의 글과같이 이유를 모른다...
    • 비슷한 에러 질문 : https://www.inflearn.com/questions/532719
  • 해결책
    • limit을 직접적으로 사용하지 않고 서브쿼리 안에 또 서브쿼리로 Room테이블의 ROOM_ID와 Image테이블의 ROOM_ID가 같은 것들 중(한 숙소 정보의 이미지 URL List)에서 image_id가 가장 작은 것 즉, 가장 먼저 생성된 Image Id 1개만 가져와서 ImageUrl을 검색하는 방식으로 해결했다.
  • 오류 해결 후 코드
    @Override
    public Slice<GetRoomsResponseDto> findAllByCategoryOrderByCreatedAt(String category, Pageable pageable, Long userId) {
        List<GetRoomsResponseDto> returnRoom = queryFactory.select(Projections.fields(
                        GetRoomsResponseDto.class,
                        room.id.as("roomId"),
                        room.title,
                        room.price,
                        room.location,
                        // imgUrl 1개만 가져오기  room.imageList.get(0) 오류남
                        ExpressionUtils.as(
                                JPAExpressions
                                        .select(image.imgUrl)
                                        .from(image)
                                        .where(image.id.eq(
                                                JPAExpressions
                                                        .select(image.id.min())
                                                        .from(image)
                                                        .where(room.id.eq(image.room.id))
                                        ))
                                        ,"imgUrl"
                        ),
                        // wish 여부
                        new CaseBuilder()
                                .when(wish.id.isNull())
                                .then((ComparableExpression<Boolean>) Expressions.asBoolean(false))
                                .otherwise(Expressions.asBoolean(true)).as("isWish")
                ))
                .distinct()
                .from(room)
                .leftJoin(wish)
                .on(room.id.eq(wish.room.id), wish.user.id.eq(userId))
                .where(getCategory(category))
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        return new SliceImpl<>(returnRoom, pageable, returnRoom.iterator().hasNext());
    }

2. Distinct no working

  • add Fetch Type Lazy in Entity Class

3. Use BooleanBuilder

profile
어떠한 가치를 창출할 수 있을까를 고민하는 개발자. 주로 Spring으로 개발해요. https://comclothing.tistory.com/ 👈🏻티스토리 블로그로 이전 완료

0개의 댓글