728x90
이 코드의 목적
제목, 글쓴이, 제목 + 내용 등을 통한 게시글 검색 기능입니다.
게시글 리스트를 불러올 때 해시태그도 보여줘야 하기 때문에 List값이 필요합니다.
이 오류는 왜 발생했을까?
Entity입니다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post extends BaseEntity{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "post_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
private String thumbnail;
@Column(length = 100, nullable = false)
private String title;
@Column(length = 100, nullable = false)
private String content;
private Long hits;
private int report;
@Enumerated(EnumType.STRING)
private Category category;
@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
private List<Comment> comment = new ArrayList<>();
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
private List<PostLike> postLike = new ArrayList<>();
@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
private List<HashTag> hashTag = new ArrayList<>();
HashTagEntity
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class HashTag {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "hashtag_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tag_id")
private Tag tag;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
Post와 HashTag는 1:N 관계입니다.
두 개를 묶은 SearchDto가 필요합니다.
DTO입니다.
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SearchTestDto {
private Long postId;
private Long userId;
private String nickname;
private String thumbnail;
private String title;
private String content;
private Long hits;
private Category category;
private Long commentCount;
private Long likeCount;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime createAt;
private List<HashTag> hashTag = new ArrayList<>();
}
Post를 조회하고, HashTag는 Left Join을 해야 합니다.
작성한 QueryDSL입니다.
public Page<SearchTestDto> searchPageSimpleV2(PostSearchCondition condition, Pageable pageable) {
System.out.println("==========================================================");
List<SearchTestDto> content = queryFactory
.select(Projections.constructor(SearchTestDto.class,
post.id,
user.id,
user.nickname,
post.thumbnail,
post.title,
post.content,
post.hits,
post.category,
post.comment.size().longValue().as("commentCount"),
post.postLike.size().longValue().as("likeCount"),
post.createAt,
post.hashTag))
.from(post)
.leftJoin(post.user, user)
.leftJoin(post.hashTag, hashTag)
.where(
titleEq(condition.getTitle())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
이 코드를 작성한 후 실행하면?
2가지 이유로 실패합니다.
- List로 조회되는 HashTag를 제대로 인식하지 못합니다.
- InnerJoin, LeftJoin이 각각 적용되어 문제가 발생합니다.
그럼 이상황에선 어떻게 하면 될까요?
해결방법
Post Entity를 직접 조회 후 그 결과로 DTO를 생성하는 것입니다.
List<Post> posts = queryFactory
.selectFrom(post)
.join(post.user, user).fetchJoin()
.where(
titleEq(condition.getTitle())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
List<SearchTestDto> content = posts.stream()
.map(p -> new SearchTestDto(p, p.getComment().size(), p.getPostLike().size()))
.collect(Collectors.toList());
문제 없이 완료!
728x90
'JPA' 카테고리의 다른 글
JPA: 알람 기능과 댓글 기능, 도메인 로직과 서비스 로직의 트랜잭션 분리 작업 (0) | 2024.06.11 |
---|---|
JPA: 페이징이 필요한 이유와 페이징 성능 개선하기 - No Offset 사용 (0) | 2024.06.05 |
JDBC, JPA) 싱글벙글 JPA 프로젝트에서 이미지 업로드 쿼리를 최소화 해보자 (0) | 2023.08.08 |
JPA: 게시글 전체 조회 N + 1를 어떻게 처리할까? (0) | 2023.03.06 |