Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development: Ensure correct @Repository annotation usage #9610

Merged
merged 1 commit into from
Oct 27, 2024

Conversation

JohannesStoehr
Copy link
Contributor

@JohannesStoehr JohannesStoehr commented Oct 27, 2024

Checklist

General

Server

Motivation and Context

During the review of #9562 we noticed that some repositories do not have the @repository annotation.

Description

Add an arch rule to verify the correct annotation usage and fix all violations. This has a cascading effect since some other arch tests only look for classes with the annotation. Therefore I also had to create two test repositories and add profile annotations above the repositories.

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Summary by CodeRabbit

  • New Features

    • Introduced new test repositories for Prerequisite and ProgrammingExerciseTask, enhancing testing capabilities.
    • Added architectural validation for repository annotations in tests.
  • Bug Fixes

    • Removed outdated methods from several repositories to streamline functionality.
  • Documentation

    • Updated annotations across multiple repository interfaces for better integration with the Spring framework.
  • Chores

    • Refactored variable types in test services to use test-specific repositories, improving test isolation.

@JohannesStoehr JohannesStoehr added this to the 7.6.5 milestone Oct 27, 2024
@JohannesStoehr JohannesStoehr self-assigned this Oct 27, 2024
@JohannesStoehr JohannesStoehr requested a review from a team as a code owner October 27, 2024 12:52
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) assessment Pull requests that affect the corresponding module atlas Pull requests that affect the corresponding module communication Pull requests that affect the corresponding module core Pull requests that affect the corresponding module iris Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module labels Oct 27, 2024
Copy link

coderabbitai bot commented Oct 27, 2024

Walkthrough

The pull request introduces several modifications across various repository interfaces to enhance their integration with the Spring framework. Key changes include the addition of @Profile(PROFILE_CORE) and @Repository annotations, which designate these interfaces as Spring-managed components and specify their active profiles. Some repositories have also seen method removals, particularly in the PrerequisiteRepository and ProgrammingExerciseTaskRepository, while new test repositories have been created for testing purposes. Overall, the changes focus on improving repository configuration without altering existing method functionalities.

Changes

File Path Change Summary
src/main/java/de/tum/cit/aet/artemis/assessment/repository/LongFeedbackTextRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository; added static import for PROFILE_CORE.
src/main/java/de/tum/cit/aet/artemis/atlas/repository/PrerequisiteRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository; removed method: findAllByCourseIdOrderById(long courseId).
src/main/java/de/tum/cit/aet/artemis/communication/repository/CustomPostRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/core/repository/AuthorityRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/core/repository/MigrationChangeRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/core/repository/PersistenceAuditEventRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTextExerciseChatSessionRepository.java Added annotations: @Profile(PROFILE_IRIS), @Repository; defined default method: findByExerciseIdAndUserIdElseThrow.
src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildPlanRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java Added annotations: @Profile(PROFILE_CORE), @Repository.
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java Removed methods: findByExerciseId(Long exerciseId), findByIdWithTestCaseAndSolutionEntriesElseThrow(long entryId). Added annotations: @Profile(PROFILE_CORE), @Repository.
src/test/java/de/tum/cit/aet/artemis/atlas/AbstractAtlasIntegrationTest.java Updated variable type from PrerequisiteRepository to PrerequisiteTestRepository.
src/test/java/de/tum/cit/aet/artemis/atlas/competency/util/PrerequisiteUtilService.java Updated variable type from PrerequisiteRepository to PrerequisiteTestRepository.
src/test/java/de/tum/cit/aet/artemis/atlas/test_repository/PrerequisiteTestRepository.java Added new interface extending PrerequisiteRepository; added method: findAllByCourseIdOrderById(long courseId).
src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationIndependentTest.java Updated variable type from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository.
src/test/java/de/tum/cit/aet/artemis/programming/test_repository/ProgrammingExerciseTaskTestRepository.java Added new interface extending ProgrammingExerciseTaskRepository; added methods for task retrieval with error handling.
src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseTestService.java Updated variable type from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository.
src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java Updated variable type from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository.
src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java Added method: shouldBeAnnotatedRepository().

Possibly related PRs

Suggested labels

tests, server, assessment, atlas, programming

Suggested reviewers

  • MaximilianAnzinger
  • coolchock
  • SimonEntholzer

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (15)
src/test/java/de/tum/cit/aet/artemis/atlas/test_repository/PrerequisiteTestRepository.java (2)

11-13: Enhance repository documentation.

While the basic documentation is present, it would be beneficial to add more context about:

  1. The test-specific purpose of this repository
  2. When it should be used (test profile)
  3. Why it's marked as @primary

Update the documentation:

 /**
  * Spring Data JPA repository for the {@link Prerequisite} entity.
+ * This is a test-specific repository that extends PrerequisiteRepository
+ * and is active only in the test profile. It's marked as @Primary to
+ * override the main repository during tests.
  */

1-19: Consider test isolation implications.

The repository is well-structured, but there are a few architectural considerations:

  1. Being marked as @primary means it will override the main repository in tests
  2. This could affect test isolation if not all tests expect this behavior
  3. Consider using specific test configurations instead of @primary for better test isolation

Consider these alternatives:

  1. Use @TestConfiguration with specific test classes instead of global @primary
  2. Create separate test slices for different testing scenarios
  3. Document which tests should use this repository to prevent unintended usage
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java (1)

Line range hint 26-45: LGTM: Well-optimized repository implementation

The implementation follows best practices for performance and maintainability:

  • Efficient fetch joins to prevent N+1 query issues
  • Proper use of Sets for collections
  • Clear method naming and null safety with Optional
  • Follows SQL practices with @param annotations and clean JPQL

Consider adding an index on exerciseId if not already present, as findByExerciseId might be frequently used.

src/main/java/de/tum/cit/aet/artemis/assessment/repository/LongFeedbackTextRepository.java (1)

Line range hint 19-45: LGTM! Well-structured JPQL queries with performance considerations.

The queries follow best practices:

  • Efficient JOIN FETCH strategy prevents N+1 queries
  • Proper parameter binding with @param
  • Clear SQL structure with uppercase keywords

Consider adding an index on feedback_id if not already present, as it's frequently used in WHERE clauses.

src/test/java/de/tum/cit/aet/artemis/programming/test_repository/ProgrammingExerciseTaskTestRepository.java (2)

17-22: Enhance class-level documentation to clarify test context usage.

While the basic documentation is present, it would be more helpful to explicitly document:

  • This is a test-specific repository
  • Why @primary is used
  • When and how this should be used in tests

Consider updating the Javadoc:

 /**
- * Spring Data repository for the ProgrammingExerciseTask entity.
+ * Test-specific Spring Data repository for the ProgrammingExerciseTask entity.
+ * This repository is marked as @Primary to override the main repository in test contexts,
+ * providing test-specific implementations and queries.
  */

24-24: Add Javadoc for findByExerciseId method.

Method documentation would improve maintainability and usage clarity.

Add documentation:

+    /**
+     * Finds all programming exercise tasks associated with a given exercise.
+     *
+     * @param exerciseId The ID of the exercise
+     * @return Set of programming exercise tasks for the exercise
+     */
     Set<ProgrammingExerciseTask> findByExerciseId(Long exerciseId);
src/main/java/de/tum/cit/aet/artemis/atlas/repository/PrerequisiteRepository.java (1)

Line range hint 24-33: Consider optimizing the fetch joins for performance

The JPQL query includes multiple LEFT JOIN FETCH operations which could impact performance for large datasets. Consider:

  1. Adding pagination support
  2. Creating separate queries for different use cases if not all joins are always needed
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java (1)

Line range hint 31-78: LGTM: Well-structured queries with efficient join fetching.

The JPQL queries are well-optimized:

  • Uses LEFT JOIN FETCH to prevent N+1 query issues
  • Properly parameterized queries
  • Clear and maintainable query structure

Consider adding database indexes for frequently queried columns like exercise.id and codeHintId if not already present, to optimize query performance.

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java (1)

Line range hint 39-44: Consider adding pagination for large result sets.

While the query is well-structured with efficient joins, the findByExerciseIdWithTestCases method returns a Set without pagination. For exercises with many solution entries, this could lead to memory pressure.

Consider implementing pagination:

-    Set<ProgrammingExerciseSolutionEntry> findByExerciseIdWithTestCases(@Param("exerciseId") long exerciseId);
+    Page<ProgrammingExerciseSolutionEntry> findByExerciseIdWithTestCases(
+        @Param("exerciseId") long exerciseId,
+        Pageable pageable
+    );

Don't forget to add the import:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildPlanRepository.java (1)

Line range hint 22-38: Consider improving query maintainability.

While the queries are well-structured, consider these improvements for better maintainability:

  1. Extract JPQL queries as constants to avoid duplication and improve maintainability
  2. Consider using named entity graphs for complex fetch joins instead of JPQL fetch joins

Example implementation:

@Repository
public interface BuildPlanRepository extends ArtemisJpaRepository<BuildPlan, Long> {
    String QUERY_WITH_PROGRAMMING_EXERCISES = """
            SELECT buildPlan
            FROM BuildPlan buildPlan
                INNER JOIN FETCH buildPlan.programmingExercises programmingExercises
            WHERE programmingExercises.id = :exerciseId
            """;
            
    @NamedEntityGraph(
        name = "BuildPlan.withProgrammingExercisesAndConfig",
        attributeNodes = {
            @NamedAttributeNode(value = "programmingExercises", subgraph = "exercises")
        },
        subgraphs = {
            @NamedSubgraph(
                name = "exercises",
                attributeNodes = @NamedAttributeNode("buildConfig")
            )
        }
    )
    
    @Query(QUERY_WITH_PROGRAMMING_EXERCISES)
    Optional<BuildPlan> findByProgrammingExercises_IdWithProgrammingExercises(@Param("exerciseId") long exerciseId);
src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTextExerciseChatSessionRepository.java (1)

Line range hint 39-46: Consider uppercase SQL keywords in JPQL queries for better readability.

While the query is functionally correct, consider using uppercase SQL keywords for better readability and consistency with SQL conventions.

 @Query("""
-            SELECT s
-                FROM IrisTextExerciseChatSession s
-                WHERE s.exercise.id = :exerciseId
-                    AND s.user.id = :userId
-                ORDER BY s.creationDate DESC
+            SELECT s
+                FROM IrisTextExerciseChatSession s
+                WHERE s.exercise.id = :exerciseId
+                    AND s.user.id = :userId
+                ORDER BY s.creationDate DESC
             """)
src/test/java/de/tum/cit/aet/artemis/atlas/AbstractAtlasIntegrationTest.java (1)

77-77: LGTM! Good architectural improvement.

The switch to PrerequisiteTestRepository is a positive architectural change because it:

  1. Improves test isolation by using a dedicated test repository
  2. Follows the established pattern seen with other test repositories in this class
  3. Aligns with the coding guideline to avoid direct DB access in tests
src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (2)

Line range hint 46-92: Consider adding pagination to prevent potential performance issues.

The findAllForCourseWithExercisesAndLectureUnitsAndLecturesAndAttachments method fetches all records with multiple LEFT JOINs. For courses with many competencies, exercises, and lecture units, this could lead to performance issues.

Consider:

  1. Adding pagination support similar to the findForImportAndUserHasAccessToCourse method
  2. Implementing lazy loading for attachments if they're not always needed
  3. Adding database indexes to optimize the join operations

Would you like me to help create a paginated version of this query?


Based on the analysis of the database schema and indexes, I can now provide a final assessment:

Consider adding indexes to optimize the mastery calculation query performance

The query uses multiple LEFT JOINs and complex conditions, but some key columns used in joins and WHERE clauses lack proper indexes:

  • Add index on student_score.user_id and student_score.exercise_id
  • Add index on team_score.team_id and team_score.exercise_id
  • Add index on student_participations.student_id and student_participations.team_id

While there are some existing indexes on exercise-related tables, the score and participation tables would benefit from additional indexes to improve the JOIN performance.

🔗 Analysis chain

Line range hint 93-127: Review the complexity of exercise mastery calculation query.

The findAllExerciseInfoByCompetencyId method contains a complex query with multiple joins and a GROUP BY clause. While the implementation is correct, consider:

Let's verify if this query has proper indexes to support its execution plan:


Let me gather more information about the database schema and indexes by checking the entity definitions and migration files.


Let me check the changelog files to see if there are proper indexes defined for the tables used in the mastery calculation query.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for index definitions related to tables used in the mastery calculation query
rg -A 5 "CREATE.*INDEX" | grep -i "student\|submission\|exercise\|team\|score"

Length of output: 185


Script:

#!/bin/bash
# Search for entity definitions and their relationships
rg -A 5 "@Entity|@Table" --type java

# Look for Liquibase or Flyway migration files that might contain index definitions
fd -e xml -e sql | grep -i "migration\|changelog"

Length of output: 281204


Script:

#!/bin/bash
# Search for index definitions in changelog files for relevant tables
for file in src/main/resources/config/liquibase/changelog/*.xml; do
  echo "=== $file ==="
  grep -A 5 "createIndex\|addIndex" "$file" | grep -i "course_competency\|exercise\|student_participation\|submission\|student_score\|team_score"
done

Length of output: 22320

src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java (1)

52-58: LGTM: Well-structured architectural test

The test method effectively enforces the @repository annotation requirement while properly handling special cases with @NoRepositoryBean. The implementation:

  • Follows the established pattern of other architectural tests
  • Correctly uses ArchUnit's fluent API
  • Properly handles empty cases for modules without repositories
  • Aligns with the PR's objective of ensuring correct @repository annotation usage

Consider adding a brief Javadoc comment to document the test's purpose and the rationale for allowing @NoRepositoryBean as an alternative, similar to other methods in this class.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6e1c562 and 561fdf9.

📒 Files selected for processing (21)
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/LongFeedbackTextRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/repository/PrerequisiteRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/communication/repository/CustomPostRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/repository/AuthorityRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/repository/MigrationChangeRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/core/repository/PersistenceAuditEventRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTextExerciseChatSessionRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildPlanRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/AbstractAtlasIntegrationTest.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/util/PrerequisiteUtilService.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/test_repository/PrerequisiteTestRepository.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationIndependentTest.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/test_repository/ProgrammingExerciseTaskTestRepository.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseTestService.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (21)
src/main/java/de/tum/cit/aet/artemis/assessment/repository/LongFeedbackTextRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/atlas/repository/PrerequisiteRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/communication/repository/CustomPostRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/repository/AuthorityRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/repository/MigrationChangeRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/core/repository/PersistenceAuditEventRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTextExerciseChatSessionRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildPlanRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/test/java/de/tum/cit/aet/artemis/atlas/AbstractAtlasIntegrationTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/atlas/competency/util/PrerequisiteUtilService.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/atlas/test_repository/PrerequisiteTestRepository.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationIndependentTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/programming/test_repository/ProgrammingExerciseTaskTestRepository.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseTestService.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

📓 Learnings (2)
src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseTestService.java (2)
Learnt from: Hialus
PR: ls1intum/Artemis#7451
File: src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTestService.java:9-9
Timestamp: 2024-10-08T15:35:48.767Z
Learning: The use of wildcard imports is acceptable in this project as specified in the `.editorconfig` file.
Learnt from: Hialus
PR: ls1intum/Artemis#7451
File: src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTestService.java:9-9
Timestamp: 2024-01-19T15:49:43.303Z
Learning: The use of wildcard imports is acceptable in this project as specified in the `.editorconfig` file.
src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java (2)
Learnt from: Hialus
PR: ls1intum/Artemis#7451
File: src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTestService.java:9-9
Timestamp: 2024-10-08T15:35:48.767Z
Learning: The use of wildcard imports is acceptable in this project as specified in the `.editorconfig` file.
Learnt from: Hialus
PR: ls1intum/Artemis#7451
File: src/test/java/de/tum/in/www1/artemis/exercise/programmingexercise/ProgrammingExerciseTestService.java:9-9
Timestamp: 2024-01-19T15:49:43.303Z
Learning: The use of wildcard imports is acceptable in this project as specified in the `.editorconfig` file.
🔇 Additional comments (46)
src/main/java/de/tum/cit/aet/artemis/core/repository/MigrationChangeRepository.java (2)

3-6: LGTM! Import statements follow guidelines.

The imports are specific and well-organized, following the coding guideline to avoid star imports.


11-12: LGTM! Annotations are correctly implemented.

The annotations align perfectly with the PR objectives:

  • @Repository properly marks this as a Spring Data repository
  • @Profile(PROFILE_CORE) correctly specifies the core profile context

Let's verify the consistent usage of these annotations across other repositories:

✅ Verification successful

Let me generate additional verification scripts to check for the @Repository annotation specifically, as the previous pattern wasn't effective:

This will help us verify:

  1. If all repository interfaces have the @Repository annotation
  2. The pattern used in IRIS repositories for annotations
  3. Whether there's a consistent pattern across different modules (core, iris, lti)

Based on the comprehensive results, I can now generate the final response:

Repository annotations are correctly and consistently implemented across the codebase

The verification confirms that:

  • All repositories have the @Repository annotation
  • Profile annotations are consistently used:
    • Core repositories use @Profile(PROFILE_CORE)
    • IRIS repositories use @Profile(PROFILE_IRIS)
    • LTI repositories use @Profile(PROFILE_LTI)
    • LDAP repositories use @Profile("ldap | ldap-only")
    • Local VCS repositories use @Profile(PROFILE_LOCALVC)

The MigrationChangeRepository follows the established pattern with both @Repository and @Profile(PROFILE_CORE) annotations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of @Repository and @Profile(PROFILE_CORE) across repositories

# Test 1: Check for repositories without @Repository annotation
echo "Checking for repositories without @Repository annotation..."
ast-grep --pattern 'interface $NAME extends $REPO { $$$$ }' | rg -v '@Repository'

# Test 2: Check for repositories without @Profile annotation
echo "Checking for repositories without @Profile annotation..."
ast-grep --pattern 'interface $NAME extends $REPO { $$$$ }' | rg -v '@Profile'

# Test 3: Check for consistent PROFILE_CORE usage
echo "Checking PROFILE_CORE usage in repositories..."
rg -l "extends.*Repository" | xargs rg "@Profile.*" | rg -v "PROFILE_CORE"

Length of output: 2152


Script:

#!/bin/bash
# Check for Repository interfaces and their annotations
echo "Checking repository interfaces and their annotations..."
rg -l "extends.*Repository" | while read -r file; do
    echo "=== $file ==="
    # Show 5 lines before any interface declaration to capture annotations
    rg "interface.*extends.*Repository" "$file" -B 5
done

# Specifically check IRIS repositories to understand their pattern
echo -e "\nChecking IRIS repositories structure..."
rg -l "extends.*Repository" src/main/java/de/tum/cit/aet/artemis/iris/repository/ | while read -r file; do
    echo "=== $file ==="
    head -n 10 "$file"
done

Length of output: 127689

src/main/java/de/tum/cit/aet/artemis/communication/repository/CustomPostRepository.java (2)

3-9: LGTM! Import statements follow best practices.

The imports are well-organized and follow the coding guidelines by avoiding star imports.


13-14: LGTM! Annotations are correctly applied.

The annotations align with the PR objectives and Spring best practices:

  • @repository enables Spring's exception translation
  • @Profile(PROFILE_CORE) ensures proper component scanning

Let's verify consistency across other repositories in the same package:

✅ Verification successful

Let me gather more information about the annotations since the previous script only showed the interface declarations.


Annotations are consistent across all repositories in the package

All repository interfaces in the communication.repository package consistently use both @Repository and @Profile(PROFILE_CORE) annotations, including the reviewed CustomPostRepository. This confirms that the annotations are correctly applied and maintain consistency with the codebase standards.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if other repositories in the same package have consistent annotations
# Expected: All repositories should have both @Repository and @Profile annotations

echo "Checking repository annotation consistency..."
rg -l "package.*communication.repository" | xargs rg -l "interface.*Repository" | while read -r file; do
    echo "=== $file ==="
    rg -A 2 "^public.*Repository" "$file"
done

Length of output: 9546


Script:

#!/bin/bash
# Check for @Repository and @Profile annotations in repository files
echo "Checking annotations in repository files..."
rg -l "package.*communication.repository" | xargs rg -B3 "^public.*Repository" | grep -E "@Repository|@Profile|^public.*Repository" --color=never

Length of output: 4563

src/main/java/de/tum/cit/aet/artemis/core/repository/AuthorityRepository.java (3)

3-8: LGTM! Import statements are well-organized.

The imports follow the coding guidelines by avoiding star imports and are properly organized.


16-17: LGTM! Annotations are correctly implemented.

The added annotations align perfectly with the PR objectives:

  • @Repository enables Spring's exception translation mechanism
  • @Profile(PROFILE_CORE) ensures proper component scanning in the core profile

Line range hint 22-24: Consider pagination for large datasets.

The getAuthorities() method uses findAll() which could be inefficient for large datasets. Consider implementing pagination if the number of authorities could grow significantly.

Let's check if this method is used in contexts where pagination might be beneficial:

If the method is frequently used, consider these improvements:

  1. Add pagination support
  2. Cache the results if authorities don't change frequently
  3. Use a more specific query if only active/specific authorities are needed
src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/CodeHintRepository.java (2)

3-13: LGTM: Clean import organization

The imports are well-organized and follow the coding guidelines by avoiding star imports.


22-23: LGTM: Correct Spring annotations added

The added annotations properly configure this as a Spring repository and specify its profile scope.

Let's verify the profile configuration is consistent across repositories:

✅ Verification successful

Let me try a different approach to verify the profile configuration across repositories:


Profile configuration is consistent across repositories

The verification shows that all repositories in the codebase consistently use the appropriate profile annotations:

  • Core repositories use @Profile(PROFILE_CORE)
  • LTI repositories use @Profile(PROFILE_LTI)
  • IRIS repositories use @Profile(PROFILE_IRIS)
  • Local VCS repositories use @Profile(PROFILE_LOCALVC)

The added @Profile(PROFILE_CORE) annotation on CodeHintRepository aligns with this pattern and is correctly configured.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent @Profile usage across repositories
# Expect: All repository classes should have @Profile(PROFILE_CORE)

echo "Checking repository profile annotations..."
ast-grep --pattern 'interface $REPO extends $_ {
  $$$
}' | while read -r file; do
  echo "Checking $file..."
  rg -A 1 '@Profile\(PROFILE_CORE\)' "$file" || echo "Missing @Profile in $file"
done

Length of output: 166277


Script:

#!/bin/bash
# Search for Java repository interfaces and their @Profile annotations
echo "Checking repository profile annotations..."
rg -t java --multiline --multiline-dotall "^@Profile.*\n.*@Repository.*interface" .

Length of output: 69253

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ExerciseHintActivationRepository.java (3)

3-11: LGTM: Import statements are well-organized.

The imports follow best practices with appropriate static imports and no wildcards.


Line range hint 19-38: Consider optimizing fetch strategy for better performance.

While the queries are well-structured, consider these optimizations:

  1. The first query eagerly fetches both exerciseHint and solutionEntries. Consider if both are always needed or if lazy loading might be more appropriate for some use cases.
  2. Consider adding an index on (exerciseHint.exercise.id, user.id) to optimize the first query.

Let's check if these fields are commonly accessed together:

#!/bin/bash
# Description: Check usage patterns of exerciseHint and solutionEntries
# to determine if eager fetching is justified

# Search for references to solutionEntries after fetching ExerciseHintActivation
rg -A 5 "findByExerciseAndUserWithExerciseHintRelations" | \
rg -A 5 "getSolutionEntries|getExerciseHint"

16-17: LGTM: Annotations align with Spring best practices.

The addition of @repository and @Profile annotations is correct and matches the PR objectives.

Let's verify the profile usage consistency:

✅ Verification successful

Let me generate another script to properly verify the profile usage, as the previous execution didn't show the expected results.


Profile and Repository annotations are correctly applied and consistent with the codebase

The verification shows that:

  1. All repository classes in the hestia package consistently use both @Profile(PROFILE_CORE) and @Repository annotations
  2. The PROFILE_CORE profile is consistently used across the entire programming module for repositories, services, and resources
  3. The annotations in ExerciseHintActivationRepository.java align with the established pattern in the codebase

The changes are verified to be correct and consistent with the codebase's architecture.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify PROFILE_CORE usage in other repository classes within the same package
# and ensure consistent profile annotation usage.

# Check for other repositories in the same package
rg -l "interface.*Repository.*extends" "src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/" | \
while read -r file; do
    echo "=== $file ==="
    rg "@Profile\(PROFILE_CORE\)" "$file" || echo "Missing @Profile"
    rg "@Repository" "$file" || echo "Missing @Repository"
done

Length of output: 3953


Script:

#!/bin/bash
# Search for repository interfaces and implementations in the hestia package
echo "=== Searching repository files ==="
fd ".*Repository.java" src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/

echo -e "\n=== Checking annotations in repository files ==="
fd ".*Repository.java" src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ -x sh -c '
    echo "File: {}"
    echo "Profile annotation:"
    rg "@Profile" {} || echo "No @Profile found"
    echo "Repository annotation:"
    rg "@Repository" {} || echo "No @Repository found"
    echo "---"
'

# Also check where PROFILE_CORE is used
echo -e "\n=== Checking PROFILE_CORE usage ==="
rg "PROFILE_CORE" src/main/java/de/tum/cit/aet/artemis/programming/

Length of output: 29435

src/main/java/de/tum/cit/aet/artemis/assessment/repository/LongFeedbackTextRepository.java (2)

3-11: LGTM! Clean import organization.

The new imports are properly organized and follow the coding guidelines by avoiding wildcard imports.


16-17: LGTM! Proper Spring repository configuration.

The added annotations correctly implement the PR objectives:

  • @repository enables Spring's exception translation
  • @Profile(PROFILE_CORE) ensures proper context activation

Let's verify consistent annotation usage across other repositories:

✅ Verification successful

Repository annotations are consistently applied across the codebase

The verification confirms that all repository interfaces in the codebase consistently have both @Repository and @Profile annotations, with appropriate profile values:

  • Core repositories use @Profile(PROFILE_CORE)
  • LTI repositories use @Profile(PROFILE_LTI)
  • IRIS repositories use @Profile(PROFILE_IRIS)
  • LDAP repositories use @Profile("ldap | ldap-only")
  • Local VCS repositories use @Profile(PROFILE_LOCALVC)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify @Repository and @Profile annotations on repository interfaces
# Expected: All repository interfaces should have both annotations

# Check for repository interfaces missing @Repository annotation
echo "Checking for missing @Repository annotations:"
rg -l "interface.*Repository.*extends" | rg -v "Test" | xargs rg -L "@Repository"

# Check for repository interfaces missing @Profile annotation
echo "Checking for missing @Profile annotations:"
rg -l "interface.*Repository.*extends" | rg -v "Test" | xargs rg -L "@Profile"

Length of output: 32175

src/test/java/de/tum/cit/aet/artemis/programming/test_repository/ProgrammingExerciseTaskTestRepository.java (2)

1-16: LGTM! Package structure and imports are well-organized.

The package naming and import organization follow best practices.


33-51: LGTM! Well-structured query with proper fetch joins.

The implementation follows best practices:

  • Efficient fetching strategy with LEFT JOIN FETCH
  • Proper null handling with Optional
  • Clear documentation
  • Good separation of concerns between the query method and the throwing wrapper

Let's verify if there are any similar fetch patterns in other test repositories that might need consolidation:

✅ Verification successful

The previous search might have been too specific. Let's broaden it to understand the overall fetch patterns in the test repositories and similar repository methods. This will help us verify if the current implementation aligns with the codebase's patterns and if any consolidation is needed.


Let's try a different approach to understand the repository patterns in the test codebase. We'll look for all query methods and repository interfaces to verify if the current implementation follows consistent patterns across the codebase.


The fetch join pattern in ProgrammingExerciseTaskTestRepository is well-implemented and consistent with the codebase patterns

After analyzing the test repositories in the codebase:

  1. The implementation follows the standard repository pattern used across the test codebase
  2. The use of LEFT JOIN FETCH is appropriate for the specific use case of loading test cases and solution entries
  3. No similar complex fetch patterns were found that would suggest a need for consolidation
  4. The repository extends the base repository correctly, similar to other test repositories in the codebase

The original review comment's approval was correct, and no consolidation or changes are needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar fetch join patterns in other test repositories
rg -t java "LEFT JOIN FETCH.*LEFT JOIN FETCH" src/test/java/

Length of output: 62


Script:

#!/bin/bash
# Let's broaden the search to find any JPQL queries with JOIN FETCH in test repositories
rg -t java "FROM.*JOIN FETCH" src/test/java/ -A 2

# Also search for similar repository methods to understand the fetch patterns
ast-grep --pattern 'interface $_ {
  $$$
  @Query($$$)
  Optional<$_> findById$_($$$);
  $$$
}'

Length of output: 273


Script:

#!/bin/bash
# Let's try a simpler search for repository interfaces and their query methods
rg -t java "@Query.*FROM" src/test/java/ -B 2 -A 2

# Also search for similar repository interfaces
rg -t java "interface.*Repository.*extends" src/test/java/ -A 2

Length of output: 16669

src/main/java/de/tum/cit/aet/artemis/atlas/repository/PrerequisiteRepository.java (3)

3-4: LGTM: Import statements follow best practices

The added imports are specific and well-organized, following Java best practices.

Also applies to: 9-12


Line range hint 65-67: Verify the impact of findByCourseIdOrderById usage

Since findAllByCourseIdOrderById was removed, ensure that findByCourseIdOrderById meets all use cases.

#!/bin/bash
# Description: Check usage of the removed and existing methods
# Expected: All callers should use findByCourseIdOrderById

echo "Checking for any remaining references to removed method:"
rg "findAllByCourseIdOrderById"

echo "Checking usage of existing method:"
rg "findByCourseIdOrderById"

21-22: LGTM: Annotations align with architectural requirements

The added annotations correctly configure this as a Spring-managed repository component within the core profile.

Let's verify consistent annotation usage across other repositories:

✅ Verification successful

This script will help us see the actual repository interfaces and their annotations, which will give us better visibility into the annotation patterns used in the codebase.


Annotations are correctly configured across repository interfaces

The verification confirms that the @Repository and @Profile annotations are consistently used across all repository interfaces in the codebase. The PrerequisiteRepository's annotations (@Profile(PROFILE_CORE) and @Repository) align with the established pattern where:

  • All repository interfaces have the @Repository annotation
  • All repository interfaces have appropriate @Profile annotations:
    • Most use @Profile(PROFILE_CORE)
    • LTI-related repositories use @Profile(PROFILE_LTI)
    • IRIS-related repositories use @Profile(PROFILE_IRIS)
    • VCS-related repositories use @Profile(PROFILE_LOCALVC)

The annotations in the reviewed code follow this consistent pattern across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify @Repository and @Profile annotations on repository interfaces
# Expected: All repository interfaces should have both annotations

# Check for repository interfaces missing @Repository annotation
echo "Checking for missing @Repository annotations:"
rg -l "interface.*Repository.*extends" | \
  xargs rg -L "@Repository"

# Check for repository interfaces missing @Profile annotation
echo "Checking for missing @Profile annotations:"
rg -l "interface.*Repository.*extends" | \
  xargs rg -L "@Profile"

Length of output: 2171


Script:

#!/bin/bash
# Let's try a different approach to verify repository annotations

# First, let's find all repository interfaces
echo "Repository interfaces in the codebase:"
rg -B 2 "interface.*Repository.*extends" --type java

# Then check specific annotation patterns
echo -e "\nChecking @Repository and @Profile patterns:"
rg -B 2 "@(Repository|Profile).*\ninterface.*Repository" --type java

Length of output: 77775


Script:

#!/bin/bash
# Let's try a more focused search for repository interfaces and their annotations

# Search for repository interfaces and their annotations with multiline support
echo "Checking repository interfaces and their annotations:"
rg -U --multiline "(@Profile.*\n)?@Repository.*\ninterface.*Repository" --type java

# Also check for any repository interfaces that might be missing either annotation
echo -e "\nChecking for repository interfaces without @Repository:"
rg -l "interface.*Repository.*extends" --type java | xargs rg -L "@Repository"

echo -e "\nChecking for repository interfaces without @Profile:"
rg -l "interface.*Repository.*extends" --type java | xargs rg -L "@Profile"

Length of output: 37015

src/test/java/de/tum/cit/aet/artemis/atlas/competency/util/PrerequisiteUtilService.java (2)

10-10: LGTM: Import change aligns with test repository usage.

The import change correctly reflects the switch to using the test-specific repository implementation.


Line range hint 1-67: Enhance test utility service with performance monitoring and reduced DB access.

The service implementation has several areas for improvement based on our testing guidelines:

  1. Direct database operations should be minimized in tests
  2. Missing query count tracking for performance monitoring
  3. Consider batching prerequisite creation to reduce DB calls

Consider these improvements:

  1. Add query count tracking:
@Service
public class PrerequisiteUtilService {
    private final QueryCountTrackerService queryTracker;
    
    public List<Prerequisite> createPrerequisites(Course course, int numberOfPrerequisites) {
        queryTracker.startTracking();
        try {
            // existing implementation
        } finally {
            queryTracker.stopTracking();
        }
    }
}
  1. Batch prerequisite creation:
public List<Prerequisite> createPrerequisites(Course course, int numberOfPrerequisites) {
    var prerequisites = new ArrayList<Prerequisite>();
    for (int i = 0; i < numberOfPrerequisites; i++) {
        var prerequisite = new Prerequisite();
        prerequisite.setTitle("Example Prerequisite" + i);
        prerequisite.setDescription("Magna pars studiorum, prodita quaerimus.");
        prerequisite.setCourse(course);
        prerequisites.add(prerequisite);
    }
    return prerequisiteRepository.saveAll(prerequisites); // Single batch save
}

Let's verify the current DB query patterns:

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseTaskRepository.java (2)

3-4: LGTM: Import statements are well-organized and specific.

The new imports are properly organized and follow the coding guidelines by avoiding wildcard imports.

Also applies to: 11-14


23-24: LGTM: Annotations correctly implement Spring repository pattern.

The added annotations properly configure this as a Spring-managed repository and specify its profile scope.

Let's verify consistent annotation usage across other repository interfaces:

✅ Verification successful

LGTM: Repository annotations are consistently applied across the codebase

The verification confirms that all repository interfaces in the codebase:

  • Have the @Repository annotation properly applied
  • Have the appropriate @Profile annotation with correct profile values (PROFILE_CORE, PROFILE_LTI, PROFILE_IRIS, etc.)

The changes to ProgrammingExerciseTaskRepository.java align with the codebase-wide pattern of repository annotation usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent @Repository and @Profile usage across repository interfaces
# Expect: All repository interfaces should have both annotations

# Test 1: Find repository interfaces missing @Repository annotation
echo "Repositories missing @Repository annotation:"
rg -l "interface.*Repository.*extends" --type java | xargs rg -L "@Repository"

# Test 2: Find repository interfaces missing @Profile annotation
echo "Repositories missing @Profile annotation:"
rg -l "interface.*Repository.*extends" --type java | xargs rg -L "@Profile"

Length of output: 36756

src/main/java/de/tum/cit/aet/artemis/programming/repository/hestia/ProgrammingExerciseSolutionEntryRepository.java (3)

3-13: LGTM! Import statements are well-organized.

The imports follow the coding guidelines, particularly avoiding star imports and using static imports appropriately for constants.


22-23: LGTM! Annotations are correctly implemented.

The annotations align with the PR objectives and follow Spring conventions:

  • @Profile(PROFILE_CORE) correctly specifies the profile
  • @repository marks this as a Spring-managed persistence component

22-24: Verify repository configuration in test context.

Let's ensure the repository is properly configured in test environments with the new profile annotation.

✅ Verification successful

Repository configuration is correctly set up for test environments

The verification shows that:

  1. The repository is properly autowired in test classes without any profile-specific configuration
  2. Test configuration files don't show any conflicting profile settings
  3. The repository is used in standard test utility classes that are part of the core test infrastructure
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test configurations and repository usage

# Test 1: Check for test configurations that might need the PROFILE_CORE
echo "Checking test configurations..."
rg -l "ProgrammingExerciseSolutionEntryRepository" "src/test"

# Test 2: Verify profile usage in test context
echo "Checking profile usage in tests..."
rg -B 3 -A 3 "PROFILE_CORE.*ProgrammingExerciseSolutionEntryRepository" "src/test"

Length of output: 484


Script:

#!/bin/bash
# Let's check how the repository is used in test files and verify test configurations

# Check the content of test files that use this repository
echo "Content of AbstractProgrammingIntegrationIndependentTest.java:"
rg -C 10 "ProgrammingExerciseSolutionEntryRepository" "src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationIndependentTest.java"

echo -e "\nContent of ProgrammingExerciseUtilService.java:"
rg -C 10 "ProgrammingExerciseSolutionEntryRepository" "src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java"

# Check test configuration files for profile settings
echo -e "\nChecking test configuration files:"
fd "application.*\.yml" "src/test" --exec cat {}

# Check for any test-specific profile annotations
echo -e "\nChecking for test profile annotations:"
rg "@Profile|@ActiveProfiles" "src/test/java/de/tum/cit/aet/artemis/programming"

Length of output: 24778

src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildPlanRepository.java (3)

3-12: LGTM! Import statements are well-organized.

The import statements follow good practices with appropriate static imports and clear organization.


18-19: LGTM! Repository annotations are correctly implemented.

The addition of @Repository and @Profile(PROFILE_CORE) annotations aligns with Spring best practices and fulfills the PR's objective of ensuring correct repository annotation usage.


18-19: Verify consistent repository annotation usage.

Let's verify that all repository interfaces have the correct annotations to ensure architectural test compliance.

✅ Verification successful

Let me analyze the results. The script checked for repository interfaces and their annotations, and found:

  1. Most test repositories are missing @Profile annotations but have @Repository
  2. All production repositories (under src/main) have both @Repository and @Profile annotations
  3. Two base repository interfaces are missing both annotations:
    • src/main/java/de/tum/cit/aet/artemis/core/repository/base/ArtemisJpaRepository.java
    • src/main/java/de/tum/cit/aet/artemis/core/repository/base/DynamicSpecificationRepository.java

Let me verify if these base interfaces are meant to have annotations by checking their purpose.


Based on the results, I can now provide a final response:

Base repository interfaces correctly omit annotations

The missing annotations on ArtemisJpaRepository and DynamicSpecificationRepository are intentional as they are base interfaces that define common repository behavior:

  • ArtemisJpaRepository is the base interface extended by all concrete repositories
  • DynamicSpecificationRepository extends ArtemisJpaRepository and adds specification capabilities
  • All concrete repository implementations that extend these base interfaces have the proper @Repository and @Profile annotations

This follows the standard Spring practice where base interfaces define contracts while concrete implementations carry the annotations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for repository interfaces missing @Repository or @Profile annotations

# Find all repository interfaces
echo "Checking repository interfaces for missing annotations..."
rg -l "interface.*Repository.*extends" --type java | while read -r file; do
    # Check for missing @Repository annotation
    if ! rg -q "@Repository" "$file"; then
        echo "Missing @Repository annotation in: $file"
    fi
    
    # Check for missing @Profile annotation
    if ! rg -q "@Profile" "$file"; then
        echo "Missing @Profile annotation in: $file"
    fi
done

Length of output: 56020


Script:

#!/bin/bash
# Check if these are abstract base classes/interfaces
echo "Checking ArtemisJpaRepository..."
rg -A 5 "interface.*ArtemisJpaRepository" src/main/java/de/tum/cit/aet/artemis/core/repository/base/ArtemisJpaRepository.java

echo -e "\nChecking DynamicSpecificationRepository..."
rg -A 5 "interface.*DynamicSpecificationRepository" src/main/java/de/tum/cit/aet/artemis/core/repository/base/DynamicSpecificationRepository.java

# Check if they are extended by other repositories
echo -e "\nChecking usage of ArtemisJpaRepository..."
rg "extends.*ArtemisJpaRepository" --type java

echo -e "\nChecking usage of DynamicSpecificationRepository..."
rg "extends.*DynamicSpecificationRepository" --type java

Length of output: 30744

src/main/java/de/tum/cit/aet/artemis/core/repository/PersistenceAuditEventRepository.java (3)

3-3: LGTM: Import statements are well-organized.

The imports follow the coding guidelines with no star imports and appropriate use of static imports for constants.

Also applies to: 13-13, 20-20


28-29: LGTM: Correct repository configuration with Spring annotations.

The annotations are properly configured:

  • @Profile(PROFILE_CORE) correctly specifies the activation profile
  • @Repository properly marks this as a Spring Data repository
  • Annotations follow the standard ordering (profile first, then stereotype)

The implementation also demonstrates good practices:

  • Uses constructor injection (via interface extension)
  • Implements efficient pagination
  • Properly uses EntityGraph for performance optimization

28-29: Verify consistent repository configuration across the codebase.

Let's ensure this repository's configuration is consistent with other repositories in the codebase.

✅ Verification successful

Repository configuration is consistent with codebase standards

The verification confirms that:

  • The @Repository annotation is correctly used in the file
  • The @Profile(PROFILE_CORE) annotation is consistently applied, matching the standard profile used across core repositories
  • This follows the same pattern as other audit-related repositories in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent repository configuration across the codebase
# Expected: All repository interfaces should have both @Repository and @Profile annotations

# Test 1: Find repository interfaces missing @Repository annotation
echo "Repositories missing @Repository annotation:"
rg -l "interface.*Repository.*extends" "src/main/java" | \
  xargs rg -L "@Repository"

# Test 2: Find repository interfaces missing @Profile annotation
echo -e "\nRepositories missing @Profile annotation:"
rg -l "interface.*Repository.*extends" "src/main/java" | \
  xargs rg -L "@Profile"

# Test 3: Verify profile consistency
echo -e "\nProfile variations used across repositories:"
rg "@Profile\((.*?)\)" "src/main/java" --only-matching | sort | uniq -c

Length of output: 117101

src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTextExerciseChatSessionRepository.java (3)

3-3: LGTM! Annotations and imports are correctly implemented.

The added annotations (@repository and @Profile) align with the PR objectives and Spring best practices. Import statements follow Java coding guidelines by avoiding star imports.

Also applies to: 11-16, 27-28


Line range hint 82-91: LGTM! Well-implemented exception handling method.

The new findByExerciseIdAndUserIdElseThrow method:

  • Correctly uses @NotNull annotation
  • Follows DRY principle by reusing existing method
  • Provides clear exception message
  • Implements proper null checking

27-28: Verify test configuration for IRIS profile.

The @Profile(PROFILE_IRIS) annotation might require corresponding test configuration updates.

✅ Verification successful

Let me gather more specific information about test configurations.


Let me check the specific test classes that might be using this repository.


Let me check one final aspect - the test classes that extend AbstractIrisIntegrationTest and might be using the repository.


Test configuration for IRIS profile is properly set up and verified

The repository is well-covered in test configurations:

  • The AbstractIrisIntegrationTest serves as the base test class with proper IRIS profile setup
  • IrisTextExerciseChatMessageIntegrationTest directly uses the repository and includes comprehensive test cases
  • Multiple other test classes extend the base test class, ensuring broad test coverage
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for test configurations using PROFILE_IRIS
rg -l "PROFILE_IRIS" "src/test"

# Search for test classes using this repository
ast-grep --pattern 'class $_ {
  $$$
  @Autowired
  private IrisTextExerciseChatSessionRepository $_;
  $$$
}'

Length of output: 1052


Script:

#!/bin/bash
# Search for IRIS profile configuration in test files
rg -A 5 "PROFILE_IRIS" "src/test/java" 

# Search for test classes with IRIS in the name
fd -e java ".*Iris.*Test\.java$" "src/test"

# Search for test configuration classes
ast-grep --pattern 'class $_ {
  $$$
  @TestConfiguration
  $$$
  @Profile("iris")
  $$$
}'

Length of output: 7283


Script:

#!/bin/bash
# Check content of relevant test files for repository usage
rg -A 5 "IrisTextExerciseChatSessionRepository" src/test/java/de/tum/cit/aet/artemis/iris/

# Check test configuration in abstract test class
cat src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java

Length of output: 5948


Script:

#!/bin/bash
# Check IrisTextExerciseChatMessageIntegrationTest which is likely to use the repository
cat src/test/java/de/tum/cit/aet/artemis/iris/IrisTextExerciseChatMessageIntegrationTest.java

# Search for repository usage in test files
rg -l "extends AbstractIrisIntegrationTest" src/test/java/de/tum/cit/aet/artemis/iris/

Length of output: 21565

src/test/java/de/tum/cit/aet/artemis/atlas/AbstractAtlasIntegrationTest.java (1)

23-23: LGTM! Consistent repository organization.

The import of PrerequisiteTestRepository aligns with the PR's objective of improving repository organization and follows the established pattern of using test-specific repositories.

src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationIndependentTest.java (2)

40-40: LGTM! Import statement follows proper organization.

The import is correctly placed with other test repository imports, maintaining a clear separation between production and test dependencies.


82-82: Verify impact on existing tests.

The change from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository looks good and aligns with the PR objectives. However, since this is a base test class, we should verify that all inheriting test classes continue to work as expected.

Let's verify the impact:

src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (2)

3-15: LGTM: Import changes are clean and follow guidelines.

The static import for PROFILE_CORE and addition of Spring annotation imports are well-organized and comply with the coding guidelines (no wildcard imports).


28-29: LGTM: Repository annotations are correctly implemented.

The addition of @Profile(PROFILE_CORE) and @repository annotations aligns with the PR objectives and Spring best practices. These annotations properly:

  • Mark this as a Spring Data repository component
  • Specify this repository as part of the core profile
src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java (2)

23-23: LGTM: Import addition is appropriate

The added import for NoRepositoryBean is necessary for the new architectural test and is correctly placed.


52-58: Verify test coverage overlap

While the test is well-implemented, let's verify there's no redundancy with existing repository validation tests.

✅ Verification successful

Let me check the actual content of these files to ensure there's no overlap in test coverage.


Let me check for any other repository-related tests in the same test class to get the complete picture.


No redundancy found in repository validation tests

After analyzing the complete test class, the shouldBeAnnotatedRepository() test is unique and complements other repository-related tests without any overlap. Each test in the class validates different aspects of repositories:

  • shouldBeNamedRepository(): Validates naming convention
  • shouldBeAnnotatedRepository(): Validates required annotations (@repository or @NoRepositoryBean)
  • shouldBeInRepositoryPackage(): Validates package structure
  • Other tests focus on different concerns like JPQL style, unused methods, etc.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential overlap with existing repository validation tests
# Look for similar repository annotation checks in test classes

echo "Searching for existing repository annotation checks..."
rg -l "Repository\.class.*should.*beAnnotated" --type java

echo "Searching for other uses of NoRepositoryBean..."
rg -l "NoRepositoryBean" --type java

Length of output: 719


Script:

#!/bin/bash
# Check the content of files for repository validation tests
echo "Content of AbstractModuleRepositoryArchitectureTest.java:"
rg -A 5 -B 5 "Repository\.class.*should.*beAnnotated" src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java

echo -e "\nChecking ArtemisJpaRepository.java and DynamicSpecificationRepository.java for NoRepositoryBean usage context:"
rg -A 2 -B 2 "NoRepositoryBean" src/main/java/de/tum/cit/aet/artemis/core/repository/base/ArtemisJpaRepository.java src/main/java/de/tum/cit/aet/artemis/core/repository/base/DynamicSpecificationRepository.java

Length of output: 3954


Script:

#!/bin/bash
# Get the full content of the test class to see all repository-related tests
echo "Full content of AbstractModuleRepositoryArchitectureTest.java:"
cat src/test/java/de/tum/cit/aet/artemis/shared/architecture/module/AbstractModuleRepositoryArchitectureTest.java

Length of output: 17045

src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseUtilService.java (2)

78-81: LGTM!

The import changes are consistent with the transition to test-specific repositories.


148-148: LGTM!

The field type change from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository aligns with the PR's objective to ensure proper repository annotation usage in test contexts.

Let's verify that the test repository is properly annotated:

✅ Verification successful

Repository annotation and test configuration verified successfully

The ProgrammingExerciseTaskTestRepository is properly configured with both @Repository and @Primary annotations, and it correctly extends ProgrammingExerciseTaskRepository. The field type change in ProgrammingExerciseUtilService is consistent with the test context setup.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that ProgrammingExerciseTaskTestRepository has the @Repository annotation
# and proper test profile configuration

ast-grep --pattern $'@Repository
$$$
interface ProgrammingExerciseTaskTestRepository'

Length of output: 210


Script:

#!/bin/bash
# Let's try a different approach using ripgrep to find the repository interface
rg -l "ProgrammingExerciseTaskTestRepository" 

# Then let's examine the content of any matching files
rg "ProgrammingExerciseTaskTestRepository" -B 3 -A 3

Length of output: 8170

src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseTestService.java (2)

150-150: LGTM: Import of test repository class

The import of ProgrammingExerciseTaskTestRepository aligns with the PR's objective to properly use test repositories in test classes.


231-231: LGTM: Updated field type to use test repository

Changed field type from ProgrammingExerciseTaskRepository to ProgrammingExerciseTaskTestRepository to properly use test repositories in test classes. This change is consistent with the architectural improvements being made.

Copy link
Contributor

@az108 az108 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for fixing this for all repositories. i hope this causes less problems in the future 👍

Copy link
Member

@krusche krusche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good 👍

@krusche krusche modified the milestones: 7.6.5, 7.6.4 Oct 27, 2024
@krusche krusche merged commit 041d5c9 into develop Oct 27, 2024
40 of 44 checks passed
@krusche krusche deleted the bugfix/development/ensure-repository-annotation branch October 27, 2024 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assessment Pull requests that affect the corresponding module atlas Pull requests that affect the corresponding module bugfix communication Pull requests that affect the corresponding module core Pull requests that affect the corresponding module iris Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module ready for review server Pull requests that update Java code. (Added Automatically!) small tests
Projects
Archived in project
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants