Skip to content

feat: Upgrade Java 17 to 21, Spring Boot 3.2 to 3.3.5, convert DTOs to records#5

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1773756829-java21-upgrade
Open

feat: Upgrade Java 17 to 21, Spring Boot 3.2 to 3.3.5, convert DTOs to records#5
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1773756829-java21-upgrade

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented Mar 17, 2026

Summary

Upgrades the project from Java 17 to Java 21 and Spring Boot 3.2.2 to 3.3.5, with dependent modernization changes:

  • pom.xml: Java 21, Spring Boot 3.3.5, springdoc-openapi 2.3.0 → 2.6.0
  • Records: Converted QuoteResult, QuoteRequest, QuoteRequestDto, QuoteResultDto, and QuoteResultDto.QuoteItemDto from mutable POJOs to Java records. Added with* copy methods on QuoteResult for immutable updates in the ranking service.
  • AbstractRankingService: Refactored from in-place mutation (setScore, setIsBestPrice, setIsRecommended) to creating new record instances, building an immutable scored list.
  • DefaultPricingEngine: getCoverMultiplier modernized to use stream API.
  • Virtual threads: Enabled via spring.threads.virtual.enabled: true in application.yml.
  • Docs: Marked Java upgrade and DTO records tasks as done in NEXT_STEPS.md and BACKLOG.md.
  • Tests: All test files updated to use record constructors; all tests pass locally on Java 21.

Review & Testing Checklist for Human

  • Thymeleaf form binding with QuoteRequestDto record: Records have no setters. @ModelAttribute binding in QuoteWebController.submitQuote() uses Spring's DataBinder, which typically needs setters to populate fields from form POST data. Jackson (@RequestBody) handles records fine, but the web form at POST /quote may silently fail or error. Manually test the quote form flow in the browser (GET /quote → fill form → submit → results page). If broken, QuoteRequestDto may need to revert to a class or a custom DataBinder configuration.
  • QuoteResult.with* methods correctness: When cheapestIdx == 0, withIsBestPrice(true) is applied at index 0, then withIsRecommended(true) overwrites index 0 again. Verify both flags are preserved (the with* method copies all fields, so it should be fine — but confirm).
  • CI environment: Verify the CI runner has Java 21 available. The local build required installing openjdk-21-jdk; CI may need a similar update to its workflow/Docker image.
  • Redundant getter methods on records: QuoteResult and QuoteRequest define explicit getXxx() methods alongside auto-generated record accessors (xxx()). These exist for backward compatibility with Thymeleaf property access and existing callers. Verify this doesn't cause issues with Jackson serialization (duplicate properties in JSON output).

Recommended test plan: Start the app locally (./mvnw spring-boot:run with Java 21), exercise the web form at /quote, the REST API at POST /api/quotes, verify Swagger UI at /swagger-ui.html, and check that results display correctly with ranking/best-price/recommended badges.

Notes

  • GeocodingService.GeoLocation was already a record — no change needed there.
  • ProviderDetailDto and QuoteResultItemDto don't exist in the codebase as separate files, so they were skipped.
  • JPA entities (Provider, CoverageOption) were intentionally not converted to records.

Link to Devin session: https://extremenetworksdemo.devinenterprise.com/sessions/a8d56f5d524f493b9fabbba3192768c3
Requested by: @bnob-git


Open with Devin

…o records

- Update pom.xml: Java 21, Spring Boot 3.3.5, springdoc-openapi 2.6.0
- Convert QuoteResult, QuoteRequest, QuoteRequestDto, QuoteResultDto to Java records
- Add with* methods on QuoteResult for immutable updates in ranking service
- Refactor AbstractRankingService to use immutable record pattern
- Modernize getCoverMultiplier with stream API
- Enable virtual threads (spring.threads.virtual.enabled=true)
- Update all tests for record constructors
- Mark Java upgrade task as done in NEXT_STEPS.md and BACKLOG.md

Co-Authored-By: bobby.nobakht <bobby.nobakht@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown
Contributor Author

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

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.

1 participant