Skip to content

Fagerdahl/exercise8.1#205

Open
Fagerdahl wants to merge 15 commits intomainfrom
fagerdahl/exercise8.1
Open

Fagerdahl/exercise8.1#205
Fagerdahl wants to merge 15 commits intomainfrom
fagerdahl/exercise8.1

Conversation

@Fagerdahl
Copy link
Copy Markdown

@Fagerdahl Fagerdahl commented Nov 13, 2025

Overview

This pull request introduces an implementation of a “Famous Movie Quotes” application.
It includes a fully working REST API, database integration, HTML view rendering via Thymeleaf and a clean UI for displaying all quotes.

What’s Included

  1. Backend — Spring Boot
  • Added Quote entity
  • Added QuoteRepository (JPA)
  • Added REST controller (/api/quotes)
  • Added Thymeleaf view controller (/quotes)
  • Configured Spring Boot with MySQL and Hibernate
  1. Database - MySQL in Docker
  • Added docker-compose.yml with:
  • MySQL latest
  • database: quotesdb
  • user/password
  • named volume for safety precautions
  • Application connects automatically using application.properties, so that spring boot knows what database to connect to.
  1. HTML Rendering (Thymeleaf)
  • Added quotes.html template
  • Displays all quotes in a table
  • Loops through data using th:each
  • Works directly with repository data from controller

How to Run

  1. Checkout my branch: fagerdahl/exercise8.1

  2. Start MySQL
    docker-compose up -d

  3. Start Spring Boot
    mvn spring-boot:run

  4. Open HTML page
    http://localhost:8080/quotes

  5. API Endpoints
    GET /api/quotes
    GET /api/quotes/{id}
    POST /api/quotes
    PUT /api/quotes/{id}
    DELETE /api/quotes/{id}

Why This PR Is Valuable

  • Connects UI + API + database in one flow
  • Demonstrates server-side rendering with real data
  • Prepares the project for further development (forms, editing, auth, etc.)
  • Easy to understand and extend

Testing

  • Verified API routes manually (Postman)
  • Verified database persistence
  • Verified HTML rendering via Thymeleaf
  • Verified styling loads correctly
  • I added integration tests using MockMvc and SpringBootTest to verify that the REST API and Spring Security work together as expected.

!IMPORTANT:
During development, IntelliJ highlighted some Lombok-generated setter methods (e.g., setQuote, setMovie, etc.) as errors.
This was an IDE issue, not a compilation issue since the project compiled successfully and all tests passed 😊

Summary by CodeRabbit

  • New Features
    • REST API for managing quotes (list, create, delete)
    • Web page showing famous movie quotes in a styled table
    • MySQL persistence with Docker Compose support
    • Basic authentication protecting API endpoints
  • Documentation
    • Added README and DEVLOG with run/test instructions and development plan
  • Tests
    • Integration tests for API endpoints and security
  • Chores
    • Migrated project to Spring Boot structure and removed legacy example app/tests

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 13, 2025

Warning

Rate limit exceeded

@Fagerdahl has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 0 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between eeb245c and 3ec8cfe.

📒 Files selected for processing (3)
  • README2.md (1 hunks)
  • docker-compose.yml (1 hunks)
  • pom.xml (3 hunks)

Walkthrough

Adds a Spring Boot application: new main class, JPA Quote entity and repository, REST and MVC controllers, Thymeleaf template, Spring Security config, Docker Compose for MySQL, Spring Boot parent POM, test infra (H2, MockMvc and tests), docs (DEVLOG/README2), IDE module file, and removes legacy example app and tests.

Changes

Cohort / File(s) Change Summary
Build & IDE
pom.xml, JavaTemplate.iml
Replace standalone POM with Spring Boot parent POM and starters (data-jpa, web, security, thymeleaf), add MySQL runtime and test deps (spring-boot-starter-test, spring-security-test, H2), add spring-boot-maven-plugin; add IntelliJ module file.
Container config
docker-compose.yml
Add MySQL service db (mysql:latest) with env vars for DB/user/password, host port 3306 mapping, and named volume quotes-mysql-data.
Application entrypoint
src/main/java/com/example/ex8/Application.java, deleted src/main/java/org/example/App.java
Add Spring Boot main class com.example.ex8.Application; remove legacy org.example.App.
Controllers (REST & MVC)
src/main/java/com/example/ex8/controller/...
src/main/java/com/example/ex8/controller/QuoteController.java, .../HomeController.java, .../QuoteViewController.java
Add REST controller for /api/quotes (GET, POST returns 201, DELETE by id) and MVC controllers for / and /quotes returning quotes view populated from repository.
Domain & Repository
src/main/java/com/example/ex8/entities/Quote.java, src/main/java/com/example/ex8/repository/QuoteRepository.java
Add JPA entity Quote (id, quote, movie, characterName → character_name, year → release_year) and QuoteRepository extending JpaRepository<Quote, Long>.
Security
src/main/java/com/example/ex8/security/SecurityConfig.java
Add SecurityConfig exposing a SecurityFilterChain bean: CSRF disabled, HTTP Basic enabled, permit root and /quotes, require authentication for /api/** and other requests per rules.
Templates & Configuration
src/main/resources/templates/quotes.html, src/main/resources/application.properties, src/main/resources/application.yml
Add Thymeleaf template quotes.html rendering a quotes table; add application properties/yml for MySQL datasource and JPA settings, Thymeleaf cache disabled, server port 8080 (both properties and YAML present).
Tests & Test Resources
src/test/java/com/example/ex8/Exercise2025ApplicationTest.java, src/test/java/com/example/ex8/quote/QuoteControllerTest.java, src/test/resources/application-test.properties, src/test/resources/schema.sql, deleted src/test/java/org/example/AppIT.java, src/test/java/org/example/AppTest.java
Add Spring Boot context-load test and MockMvc-based QuoteController tests (auth/unauth scenarios); add H2 test DB config and schema.sql for quotes table; remove legacy tests.
Docs & Dev Notes
DEVLOG.md, README2.md
Add DEVLOG with development plan and task checklist; add README2 describing app, endpoints, and Docker/MySQL run instructions.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Security
    participant QuoteController
    participant QuoteRepo
    participant DB

    rect `#f2f9ff`
    Note over Client,Security: Unauthenticated REST request
    Client->>Security: GET /api/quotes
    Security-->>Client: 401 Unauthorized
    end

    rect `#f6fff2`
    Note over Client,DB: Authenticated REST request
    Client->>Security: GET /api/quotes (with credentials)
    Security->>QuoteController: forward request
    QuoteController->>QuoteRepo: findAll()
    QuoteRepo->>DB: SELECT * FROM quotes
    DB-->>QuoteRepo: rows
    QuoteRepo-->>QuoteController: List<Quote>
    QuoteController-->>Client: 200 OK + JSON
    end
Loading
sequenceDiagram
    participant Browser
    participant QuoteViewController
    participant QuoteRepo
    participant Thymeleaf

    Browser->>QuoteViewController: GET /quotes
    QuoteViewController->>QuoteRepo: findAll()
    QuoteRepo-->>QuoteViewController: List<Quote>
    QuoteViewController->>Thymeleaf: render quotes.html with model
    Thymeleaf-->>Browser: HTML table of quotes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • pom.xml: dependency versions, Java 21 and Spring Boot compatibility, plugin config.
    • Duplicate datasource configuration in application.properties and application.yml (potential conflicts).
    • SecurityConfig: route rules, CSRF disabled choice, and alignment with controller tests.
    • Entity mapping vs test schema.sql: column names (character_name, release_year) and types.
    • QuoteController vs QuoteControllerTest: authentication setup and expected response codes.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fagerdahl/exercise8.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Fagerdahl
Copy link
Copy Markdown
Author

Skärmbild 2025-11-13 184849 Skärmbild 2025-11-13 184841

Copy link
Copy Markdown

@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: 12

♻️ Duplicate comments (1)
src/main/resources/application.yml (1)

1-18: Duplicate configuration detected.

This file duplicates the configuration in application.properties. See the comment on that file for details.

🧹 Nitpick comments (7)
src/main/resources/application.properties (1)

3-6: Consider security implications for production.

The connection string uses useSSL=false and credentials are hardcoded. While acceptable for local development and exercises, consider:

  • Enabling SSL for production environments
  • Externalizing credentials via environment variables or Spring profiles
DEVLOG.md (1)

1-62: Consider minor markdown formatting improvements.

Static analysis tools flagged a few formatting issues:

  • Bare URLs (lines 19, 22, 25, 26) should be formatted as markdown links
  • Heading level on line 25 should increment by one level
  • Minor spelling consideration: "webapp" vs "web app"

These are purely cosmetic and can be addressed at your convenience.

pom.xml (1)

33-35: Remove unused dependency version properties.

The properties junit.jupiter.version, assertj.core.version, and mockito.version are declared but never used. Spring Boot's dependency management already controls these versions through the parent POM. These properties can be safely removed.

-    <junit.jupiter.version>5.13.4</junit.jupiter.version>
-    <assertj.core.version>3.27.6</assertj.core.version>
-    <mockito.version>5.20.0</mockito.version>
src/main/java/com/example/ex8/controller/QuoteController.java (2)

25-31: Consider adding input validation for POST endpoint.

The endpoint accepts Quote objects without validation. Consider adding @Valid annotation and appropriate constraints on the Quote entity to ensure data integrity.

Example:

+import jakarta.validation.Valid;
+
 @PostMapping
-public ResponseEntity<Quote> create(@RequestBody Quote quote) {
+public ResponseEntity<Quote> create(@Valid @RequestBody Quote quote) {
     Quote saved = repo.save(quote);
     return ResponseEntity
             .status(HttpStatus.CREATED)
             .body(saved);
 }

Then add validation annotations to the Quote entity (e.g., @NotBlank, @NotNull).


20-23: Consider pagination for the GET all quotes endpoint.

Returning all quotes without pagination could cause performance issues as the dataset grows. Consider adding pagination support using Spring Data's Pageable.

Example:

@GetMapping
public Page<Quote> getAll(Pageable pageable) {
    return repo.findAll(pageable);
}
src/main/java/com/example/ex8/entities/Quote.java (2)

13-20: Consider adding validation constraints.

The entity fields lack validation annotations, which could allow invalid data to be persisted. Consider adding constraints to ensure data integrity.

Apply this diff to add validation:

 package com.example.ex8.entities;
 
 import jakarta.persistence.*;
+import jakarta.validation.constraints.*;
 
 @Entity
 @Table(name = "quotes")
 public class Quote {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
+    @NotBlank(message = "Quote text cannot be blank")
+    @Size(max = 500, message = "Quote text cannot exceed 500 characters")
     private String quote;
 
+    @NotBlank(message = "Movie name cannot be blank")
+    @Size(max = 200, message = "Movie name cannot exceed 200 characters")
     private String movie;
 
     @Column(name = "character_name")
+    @NotBlank(message = "Character name cannot be blank")
+    @Size(max = 100, message = "Character name cannot exceed 100 characters")
     private String characterName;
 
+    @Min(value = 1800, message = "Year must be 1800 or later")
+    @Max(value = 2100, message = "Year must be 2100 or earlier")
     private Integer year;

1-75: Consider adding equals, hashCode, and toString methods.

The entity lacks equals, hashCode, and toString implementations, which are best practices for JPA entities to ensure correct behavior in collections, caching, and debugging scenarios.

You can manually add these methods or use Lombok to reduce boilerplate:

 package com.example.ex8.entities;
 
 import jakarta.persistence.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.AllArgsConstructor;
 
 @Entity
 @Table(name = "quotes")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class Quote {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
     private String quote;
     
     private String movie;
     
     @Column(name = "character_name")
     private String characterName;
     
     private Integer year;
-
-    public Quote() {
-    }
-
-    public Quote(String quote, String movie, String characterName, Integer year) {
-        this.quote = quote;
-        this.movie = movie;
-        this.characterName = characterName;
-        this.year = year;
-    }
-
-    // Remove all manual getters/setters when using @Data
 }

Note: If using Lombok, ensure lombok.allArgsConstructor.addConstructorProperties=true is set in lombok.config for JPA compatibility, or use @AllArgsConstructor(access = AccessLevel.PROTECTED) with a separate public factory method.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8618163 and d2ffccd.

⛔ Files ignored due to path filters (1)
  • img.png is excluded by !**/*.png
📒 Files selected for processing (20)
  • DEVLOG.md (1 hunks)
  • JavaTemplate.iml (1 hunks)
  • README2.md (1 hunks)
  • docker-compose.yml (1 hunks)
  • pom.xml (3 hunks)
  • src/main/java/com/example/ex8/Application.java (1 hunks)
  • src/main/java/com/example/ex8/controller/HomeController.java (1 hunks)
  • src/main/java/com/example/ex8/controller/QuoteController.java (1 hunks)
  • src/main/java/com/example/ex8/controller/QuoteViewController.java (1 hunks)
  • src/main/java/com/example/ex8/entities/Quote.java (1 hunks)
  • src/main/java/com/example/ex8/repository/QuoteRepository.java (1 hunks)
  • src/main/java/com/example/ex8/security/SecurityConfig.java (1 hunks)
  • src/main/java/org/example/App.java (0 hunks)
  • src/main/resources/application.properties (1 hunks)
  • src/main/resources/application.yml (1 hunks)
  • src/main/resources/templates/quotes.html (1 hunks)
  • src/test/java/com/example/ex8/Exercise2025ApplicationTest.java (1 hunks)
  • src/test/java/com/example/ex8/quote/QuoteControllerTest.java (1 hunks)
  • src/test/java/org/example/AppIT.java (0 hunks)
  • src/test/java/org/example/AppTest.java (0 hunks)
💤 Files with no reviewable changes (3)
  • src/test/java/org/example/AppTest.java
  • src/main/java/org/example/App.java
  • src/test/java/org/example/AppIT.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-10T14:02:54.365Z
Learnt from: alfredbrannare
Repo: fungover/exercise2025 PR: 66
File: src/test/java/org/example/service/WarehouseTest.java:1-21
Timestamp: 2025-09-10T14:02:54.365Z
Learning: In the fungover/exercise2025 project, static mocking of LocalDateTime.now() works successfully with the existing Mockito setup without requiring mockito-inline dependency.

Applied to files:

  • src/test/java/com/example/ex8/Exercise2025ApplicationTest.java
🧬 Code graph analysis (2)
src/main/java/com/example/ex8/controller/QuoteViewController.java (1)
src/main/java/com/example/ex8/controller/HomeController.java (1)
  • Controller (6-13)
src/main/java/com/example/ex8/controller/HomeController.java (1)
src/main/java/com/example/ex8/controller/QuoteViewController.java (1)
  • Controller (8-22)
🪛 LanguageTool
DEVLOG.md

[grammar] ~7-~7: Ensure spelling is correct
Context: ... decomposed: - I am supposed to build a webapp (a REST API + HTML) with Spring Boot. -...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
README2.md

19-19: Bare URL used

(MD034, no-bare-urls)


22-22: Bare URL used

(MD034, no-bare-urls)


25-25: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


25-25: Bare URL used

(MD034, no-bare-urls)


26-26: Bare URL used

(MD034, no-bare-urls)

DEVLOG.md

19-19: Bare URL used

(MD034, no-bare-urls)


22-22: Bare URL used

(MD034, no-bare-urls)


25-25: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


25-25: Bare URL used

(MD034, no-bare-urls)


26-26: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (13)
JavaTemplate.iml (1)

8-11: Review duplicate and unusual source folder configurations.

Lines 8-11 contain potentially problematic configurations:

  • src/main/java appears twice (lines 8-9) with different type attributes
  • src/main/resources appears twice (lines 10-11) with different type attributes
  • Using type="java-resource" for source folders is unusual

Verify if this configuration is intentional or if it should be simplified to standard Maven source folder structure.

docker-compose.yml (1)

6-9: Hardcoded credentials acceptable for development.

The hardcoded database credentials are suitable for local development and learning exercises. For production deployments, these should be externalized via environment variables or secrets management.

src/main/java/com/example/ex8/controller/HomeController.java (1)

6-12: LGTM!

The controller correctly maps the root path to the "quotes" Thymeleaf view. This provides convenient access to the quotes UI alongside the /quotes endpoint in QuoteViewController.

src/test/java/com/example/ex8/Exercise2025ApplicationTest.java (1)

6-11: LGTM!

This smoke test correctly verifies that the Spring application context loads successfully. The empty test body is intentional and appropriate for this purpose.

pom.xml (1)

37-83: No Lombok dependency required or used.

Verification found zero Lombok references, annotations, or dependencies in the codebase. All getters and setters in Quote.java and other entities are manually implemented. The PR objectives mentioned in this review appear to be incorrect or outdated; there are no Lombok-generated setters causing IDE errors.

Likely an incorrect or invalid review comment.

src/main/resources/templates/quotes.html (1)

63-68: LGTM! Proper XSS protection.

The Thymeleaf data binding uses th:text which automatically escapes HTML content, protecting against XSS attacks. The field references align correctly with the Quote entity.

src/main/java/com/example/ex8/repository/QuoteRepository.java (1)

6-7: LGTM! Clean Spring Data JPA repository.

The repository interface follows Spring Data JPA conventions correctly. The empty interface body will be automatically implemented by Spring with standard CRUD operations.

src/main/java/com/example/ex8/Application.java (1)

6-11: LGTM! Standard Spring Boot entry point.

The application class follows Spring Boot conventions correctly with the standard bootstrap pattern.

src/main/java/com/example/ex8/controller/QuoteViewController.java (1)

17-21: LGTM! Clean view controller implementation.

The controller correctly fetches all quotes from the repository and populates the model for Thymeleaf rendering. Constructor-based dependency injection is properly used.

src/test/java/com/example/ex8/quote/QuoteControllerTest.java (1)

67-68: The review comment is incorrect and should be dismissed.

The Quote entity has a quote field (not text), and the Thymeleaf template correctly references ${q.quote} which calls getQuote(). The setText() and getText() methods are alternative accessors that delegate to the existing quote field—they don't indicate the presence of a separate text field. The test code correctly uses quote.setText(), which works as intended.

Likely an incorrect or invalid review comment.

src/main/java/com/example/ex8/entities/Quote.java (3)

5-11: LGTM: Entity structure is well-defined.

The entity declaration and ID field configuration follow standard JPA practices. The IDENTITY generation strategy is appropriate for MySQL auto-increment columns.


22-30: LGTM: Constructors follow JPA requirements.

The no-arg constructor satisfies JPA requirements, and the full-argument constructor provides a convenient way to create new entities. Correctly excludes id since it's auto-generated.


32-66: LGTM: Standard JavaBean accessors implemented correctly.

All getters and setters follow JavaBean conventions. The absence of a setter for id is appropriate for auto-generated primary keys.

Comment thread docker-compose.yml Outdated
Comment thread JavaTemplate.iml
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/exercise8" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/exercise8/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/exercise8/src/test/java" isTestSource="false" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incorrect test source configuration.

The exercise8/src/test/java folder is marked with isTestSource="false", which is incorrect. Test sources should be marked with isTestSource="true" for proper IDE recognition and test runner integration.

Apply this fix:

-      <sourceFolder url="file://$MODULE_DIR$/exercise8/src/test/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/exercise8/src/test/java" isTestSource="true" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<sourceFolder url="file://$MODULE_DIR$/exercise8/src/test/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/exercise8/src/test/java" isTestSource="true" />
🤖 Prompt for AI Agents
In JavaTemplate.iml around line 7, the sourceFolder entry for
exercise8/src/test/java is incorrectly marked isTestSource="false"; change that
attribute to isTestSource="true" so the IDE treats the folder as test sources.
Update only that sourceFolder element to set isTestSource="true" (ensuring no
other attributes are altered) so test runner and IDE recognize the test
directory.

Comment thread pom.xml
Comment on lines +30 to 31
<java.version>21</java.version>
<maven.compiler.release>25</maven.compiler.release>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix critical Java version mismatch.

Line 30 declares java.version=21 but line 31 sets maven.compiler.release=25. Java 25 does not exist yet (current LTS is Java 21, latest is Java 23). This mismatch will cause compilation issues.

Apply this fix:

     <java.version>21</java.version>
-    <maven.compiler.release>25</maven.compiler.release>
+    <maven.compiler.release>21</maven.compiler.release>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<java.version>21</java.version>
<maven.compiler.release>25</maven.compiler.release>
<java.version>21</java.version>
<maven.compiler.release>21</maven.compiler.release>
🤖 Prompt for AI Agents
In pom.xml around lines 30-31, there is a Java version mismatch: java.version is
21 but maven.compiler.release is 25; change maven.compiler.release to 21 (or
make both properties the same valid Java version) so the compiler release
matches java.version and uses a supported JDK (e.g., set
<maven.compiler.release>21</maven.compiler.release>).

Comment thread README2.md Outdated
Comment thread README2.md
Comment on lines +68 to +74
public String getText() {
return quote;
}

public void setText(String text) {
this.quote = text;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove duplicate accessors to avoid confusion.

The getText/setText methods are aliases for getQuote/setQuote, creating two ways to access the same field. This violates the single-source-of-truth principle and can lead to:

  • Inconsistent usage across the codebase
  • Serialization issues where both "quote" and "text" appear in JSON/XML
  • Confusion for developers and API consumers

If the Thymeleaf template uses text instead of quote, update the template to use quote consistently.

Apply this diff to remove the duplicate accessors:

     public void setYear(Integer year) {
         this.year = year;
     }
-
-    public String getText() {
-        return quote;
-    }
-
-    public void setText(String text) {
-        this.quote = text;
-    }
 }

If the Thymeleaf template references ${quote.text}, update it to use ${quote.quote}:

<!-- In quotes.html, change: -->
<td th:text="${quote.text}"></td>
<!-- To: -->
<td th:text="${quote.quote}"></td>
🤖 Prompt for AI Agents
In src/main/java/com/example/ex8/entities/Quote.java around lines 68 to 74,
remove the duplicate accessor methods getText() and setText(String) so there is
only a single canonical pair getQuote()/setQuote() for the field; update any
Thymeleaf templates (e.g., quotes.html) that reference ${quote.text} to
${quote.quote} and search the codebase for uses of .getText()/.setText() and
replace them with .getQuote()/.setQuote() to avoid duplicate JSON/XML properties
and developer confusion.

Comment thread src/main/java/com/example/ex8/security/SecurityConfig.java
Comment on lines +1 to +15
spring.application.name=exercise2025

spring.datasource.url=jdbc:mysql://localhost:3306/quotesdb?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=quotesuser
spring.datasource.password=quotespass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

spring.thymeleaf.cache=false

server.port=8080
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove duplicate configuration file.

Both application.properties and application.yml exist with identical configurations. Spring Boot will load both, which creates maintenance overhead and potential confusion. Choose one format and remove the other.

#!/bin/bash
# Verify both configuration files exist with overlapping settings
echo "=== application.properties ==="
cat src/main/resources/application.properties
echo ""
echo "=== application.yml ==="
cat src/main/resources/application.yml
🤖 Prompt for AI Agents
In src/main/resources/application.properties lines 1-15: this properties file
duplicates the settings found in application.yml; remove the duplication by
choosing one format (properties or YAML), delete the other file from
src/main/resources, and ensure any unique keys from either file are merged
before removal; update any documentation or deployment scripts that reference
the deleted filename and run the app/tests to verify no missing configuration or
profile-specific overrides were lost.

Comment thread src/main/resources/templates/quotes.html
Comment thread src/test/java/com/example/ex8/quote/QuoteControllerTest.java
@Fagerdahl Fagerdahl force-pushed the fagerdahl/exercise8.1 branch from d2ffccd to 0579c13 Compare November 20, 2025 15:37
Copy link
Copy Markdown

@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: 0

♻️ Duplicate comments (1)
src/main/resources/application.properties (1)

1-16: Verify no duplicate configuration with application.yml.

A prior review flagged both application.properties and application.yml as duplicates. If both files exist, consolidate to one format to avoid maintenance overhead and configuration conflicts.

Run the following to verify:

#!/bin/bash
# Check if both application.properties and application.yml exist
ls -la src/main/resources/application.properties src/main/resources/application.yml 2>&1
🧹 Nitpick comments (1)
src/test/resources/schema.sql (1)

1-9: Schema structure is correct and aligns with Quote entity.

The table definition correctly maps to the Quote entity fields. For consistency with professional standards, consider replacing the informal comment with a more descriptive one, e.g., -- Quote entity table for test initialization.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2ffccd and 0579c13.

📒 Files selected for processing (8)
  • JavaTemplate.iml (1 hunks)
  • pom.xml (1 hunks)
  • src/main/java/com/example/ex8/entities/Quote.java (1 hunks)
  • src/main/java/com/example/ex8/security/SecurityConfig.java (1 hunks)
  • src/main/resources/application.properties (1 hunks)
  • src/test/java/com/example/ex8/quote/QuoteControllerTest.java (1 hunks)
  • src/test/resources/application-test.properties (1 hunks)
  • src/test/resources/schema.sql (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/java/com/example/ex8/security/SecurityConfig.java
  • JavaTemplate.iml
  • src/test/java/com/example/ex8/quote/QuoteControllerTest.java
  • src/main/java/com/example/ex8/entities/Quote.java
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.
📚 Learning: 2025-11-16T13:56:11.263Z
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.

Applied to files:

  • src/main/resources/application.properties
  • pom.xml
🔇 Additional comments (4)
src/test/resources/application-test.properties (1)

1-14: Test configuration is well-structured and follows best practices.

H2 in-memory database, schema initialization via schema.sql, and correct Hibernate DDL mode (none) align well with testing patterns. This isolates tests from production database and enables fast, repeatable test runs.

pom.xml (3)

5-31: Spring Boot parent and Java version correctly configured.

The migration to Spring Boot parent (3.5.7) with java.version=21 and release=${java.version} is consistent and resolves the prior version mismatch issue. Java 21 is a supported LTS version.


32-82: Dependencies are appropriate for Spring Boot application stack.

Spring Boot starters (data-jpa, security, thymeleaf, web, validation), runtime dependencies (MySQL, devtools), and test dependencies (H2, spring-security-test) are correctly scoped and align with the application architecture. The shift from standalone JUnit/Mockito to Spring Boot testing is well-executed.


86-101: Build configuration is correctly simplified for Spring Boot.

maven-compiler-plugin now delegates to the parent POM version, spring-boot-maven-plugin is properly added, and unnecessary plugins have been removed. Build setup supports the Spring Boot application lifecycle.

Copy link
Copy Markdown

@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: 0

♻️ Duplicate comments (1)
pom.xml (1)

30-31: Fix critical Java version mismatch (duplicate issue from previous review).

Line 30 declares java.version=21 (valid) but line 31 sets maven.compiler.release=25 (invalid—Java 25 does not exist yet; the latest is Java 23, and the current LTS is Java 21). This mismatch will cause compilation failures.

Apply this fix:

     <java.version>21</java.version>
-    <maven.compiler.release>25</maven.compiler.release>
+    <maven.compiler.release>21</maven.compiler.release>
🧹 Nitpick comments (2)
pom.xml (2)

33-35: Remove unused version properties.

The properties junit.jupiter.version, assertj.core.version, and mockito.version are no longer used in the dependency tree because Spring Boot parent (3.5.7) manages transitive versions for JUnit, AssertJ, and Mockito. Removing them reduces maintenance burden and clarifies intent.

     <properties>
         <java.version>21</java.version>
         <maven.compiler.release>21</maven.compiler.release>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <junit.jupiter.version>5.13.4</junit.jupiter.version>
-        <assertj.core.version>3.27.6</assertj.core.version>
-        <mockito.version>5.20.0</mockito.version>
     </properties>

16-28: Address empty metadata placeholders.

The metadata sections (url, licenses, developers, scm) are defined but contain empty or placeholder values. While acceptable for a learning exercise, populate these with meaningful content for a production-ready artifact, or remove the sections if not applicable.

For an exercise project (as per learnings on the fungover/exercise2025 repository), this is acceptable and can remain as-is.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0579c13 and 7b8e32e.

📒 Files selected for processing (1)
  • pom.xml (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.
🔇 Additional comments (1)
pom.xml (1)

5-10: Spring Boot migration structure and dependencies look solid.

The migration from standalone Maven to Spring Boot parent (3.5.7) is well-aligned with the application's needs:

  • Spring Data JPA, Web, Security, Thymeleaf, and Validation starters added appropriately.
  • MySQL connector scoped to runtime, H2 to test scope for integration tests.
  • Spring Security Test and Thymeleaf Security extras included for testing and rendering.
  • Jacoco configuration correctly references the java.version property.
  • spring-boot-maven-plugin added to enable Spring Boot-specific Maven features.

Please verify that Spring Boot 3.5.7 is still the intended version for this project given the current date is November 2025 (beyond the knowledge cutoff). If a newer stable release is available, consider upgrading.

Also applies to: 39-87, 121-121, 125-127

@Fagerdahl Fagerdahl force-pushed the fagerdahl/exercise8.1 branch from 7b8e32e to eeb245c Compare November 20, 2025 16:00
Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
src/test/resources/application-test.properties (1)

11-13: Consider setting spring.sql.init.continue-on-error=false for tests.

Allowing errors to be silently ignored during schema initialization can mask issues in your test setup. Tests should typically fail fast when schema initialization fails.

Apply this diff:

-spring.sql.init.continue-on-error=true
+spring.sql.init.continue-on-error=false
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b8e32e and eeb245c.

📒 Files selected for processing (2)
  • src/test/java/com/example/ex8/Exercise2025ApplicationTest.java (1 hunks)
  • src/test/resources/application-test.properties (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.
📚 Learning: 2025-09-10T14:02:54.365Z
Learnt from: alfredbrannare
Repo: fungover/exercise2025 PR: 66
File: src/test/java/org/example/service/WarehouseTest.java:1-21
Timestamp: 2025-09-10T14:02:54.365Z
Learning: In the fungover/exercise2025 project, static mocking of LocalDateTime.now() works successfully with the existing Mockito setup without requiring mockito-inline dependency.

Applied to files:

  • src/test/java/com/example/ex8/Exercise2025ApplicationTest.java
📚 Learning: 2025-11-16T13:56:11.263Z
Learnt from: jennymakki
Repo: fungover/exercise2025 PR: 204
File: src/main/java/org/example/config/SecurityConfig.java:19-24
Timestamp: 2025-11-16T13:56:11.263Z
Learning: The repository fungover/exercise2025 is an exercise/learning project where hard-coded credentials and other shortcuts for ease of testing are acceptable and intentional.

Applied to files:

  • src/test/java/com/example/ex8/Exercise2025ApplicationTest.java
🔇 Additional comments (1)
src/test/java/com/example/ex8/Exercise2025ApplicationTest.java (1)

7-13: LGTM!

This is a standard Spring Boot context loading test. The @ActiveProfiles("test") correctly activates the test configuration, and the empty test method appropriately verifies that the application context loads without errors.

Fagerdahl and others added 3 commits November 20, 2025 17:04
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants