diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/repository/ConversationMessageRepository.java b/src/main/java/de/tum/cit/aet/artemis/communication/repository/ConversationMessageRepository.java index 21b3dfac0b81..a7268c5d7a69 100644 --- a/src/main/java/de/tum/cit/aet/artemis/communication/repository/ConversationMessageRepository.java +++ b/src/main/java/de/tum/cit/aet/artemis/communication/repository/ConversationMessageRepository.java @@ -5,7 +5,6 @@ import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getConversationsSpecification; import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getCourseWideChannelsSpecification; import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getOwnSpecification; -import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getSearchTextSpecification; import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getSortSpecification; import static de.tum.cit.aet.artemis.communication.repository.MessageSpecs.getUnresolvedSpecification; import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE; @@ -53,7 +52,6 @@ public interface ConversationMessageRepository extends ArtemisJpaRepository configureSearchSpecification(Specification specification, PostContextFilterDTO postContextFilter, long userId) { return specification // @formatter:off - .and(getSearchTextSpecification(postContextFilter.searchText())) .and(getOwnSpecification(Boolean.TRUE.equals(postContextFilter.filterToOwn()), userId)) .and(getAnsweredOrReactedSpecification(Boolean.TRUE.equals(postContextFilter.filterToAnsweredOrReacted()), userId)) .and(getUnresolvedSpecification(Boolean.TRUE.equals(postContextFilter.filterToUnresolved()))) @@ -72,8 +70,9 @@ private Specification configureSearchSpecification(Specification spe default Page findMessages(PostContextFilterDTO postContextFilter, Pageable pageable, long userId) { var specification = Specification.where(getConversationSpecification(postContextFilter.conversationId())); specification = configureSearchSpecification(specification, postContextFilter, userId); + String searchText = postContextFilter.searchText() != null ? postContextFilter.searchText() : ""; // Fetch all necessary attributes to avoid lazy loading (even though relations are defined as EAGER in the domain class, specification queries do not respect this) - return findPostsWithSpecification(pageable, specification); + return findPostsWithSpecification(pageable, specification, searchText); } /** @@ -88,17 +87,18 @@ default Page findCourseWideMessages(PostContextFilterDTO postContextFilter var specification = Specification.where(getCourseWideChannelsSpecification(postContextFilter.courseId())) .and(getConversationsSpecification(postContextFilter.courseWideChannelIds())); specification = configureSearchSpecification(specification, postContextFilter, userId); - return findPostsWithSpecification(pageable, specification); + String searchText = postContextFilter.searchText() != null ? postContextFilter.searchText() : ""; + return findPostsWithSpecification(pageable, specification, searchText); } - private PageImpl findPostsWithSpecification(Pageable pageable, Specification specification) { + private PageImpl findPostsWithSpecification(Pageable pageable, Specification specification, String searchText) { // Only fetch the postIds without any left joins to avoid that Hibernate loads all objects and creates the page in Java long start = System.nanoTime(); Page postIds = findPostIdsWithSpecification(specification, pageable); log.debug("findPostIdsWithSpecification took {}", TimeLogUtil.formatDurationFrom(start)); // Fetch all necessary attributes to avoid lazy loading (even though relations are defined as EAGER in the domain class, specification queries do not respect this) long start2 = System.nanoTime(); - List posts = findByPostIdsWithEagerRelationships(postIds.getContent()); + List posts = findByPostIdsWithEagerRelationships(postIds.getContent(), searchText); // Make sure to sort the posts in the same order as the postIds Map postMap = posts.stream().collect(Collectors.toMap(Post::getId, post -> post)); posts = postIds.stream().map(postMap::get).toList(); @@ -118,9 +118,9 @@ private PageImpl findPostsWithSpecification(Pageable pageable, Specificati LEFT JOIN FETCH a.reactions LEFT JOIN FETCH a.post LEFT JOIN FETCH a.author - WHERE p.id IN :postIds + WHERE p.id IN :postIds and (p.content like %:searchText% OR a.content like %:searchText%) """) - List findByPostIdsWithEagerRelationships(@Param("postIds") List postIds); + List findByPostIdsWithEagerRelationships(@Param("postIds") List postIds, @Param("searchText") String searchText); default Post findMessagePostByIdElseThrow(Long postId) throws EntityNotFoundException { return getValueElseThrow(findById(postId).filter(post -> post.getConversation() != null), postId); diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/repository/MessageSpecs.java b/src/main/java/de/tum/cit/aet/artemis/communication/repository/MessageSpecs.java index 938eb9d7a8d3..1ba8ddb0f15b 100644 --- a/src/main/java/de/tum/cit/aet/artemis/communication/repository/MessageSpecs.java +++ b/src/main/java/de/tum/cit/aet/artemis/communication/repository/MessageSpecs.java @@ -19,7 +19,6 @@ import de.tum.cit.aet.artemis.communication.domain.PostSortCriterion; import de.tum.cit.aet.artemis.communication.domain.Post_; import de.tum.cit.aet.artemis.communication.domain.Reaction_; -import de.tum.cit.aet.artemis.communication.domain.conversation.Channel; import de.tum.cit.aet.artemis.communication.domain.conversation.Channel_; import de.tum.cit.aet.artemis.communication.domain.conversation.Conversation_; import de.tum.cit.aet.artemis.core.domain.Course_; @@ -93,11 +92,11 @@ public static Specification getCourseWideChannelsSpecification(Long course return (root, query, criteriaBuilder) -> { final var conversationJoin = root.join(Post_.conversation, JoinType.LEFT); final var isInCoursePredicate = criteriaBuilder.equal(conversationJoin.get(Channel_.COURSE).get(Course_.ID), courseId); - final var isCourseWidePredicate = criteriaBuilder.isTrue(conversationJoin.get(Channel_.IS_COURSE_WIDE)); + // final var isCourseWidePredicate = criteriaBuilder.isTrue(conversationJoin.get(Channel_.IS_COURSE_WIDE)); // make sure we only fetch channels (which are sub types of conversations) // this avoids the creation of sub queries - final var isChannelPredicate = criteriaBuilder.equal(conversationJoin.type(), criteriaBuilder.literal(Channel.class)); - return criteriaBuilder.and(isInCoursePredicate, isCourseWidePredicate, isChannelPredicate); + // final var isChannelPredicate = criteriaBuilder.equal(conversationJoin.type(), criteriaBuilder.literal(Channel.class)); + return criteriaBuilder.and(isInCoursePredicate); }; }