Complete .NET Framework 4.7.2 → Java 21 / Spring Boot 3.5 Migration — eShopLegacyMVC#155
Open
devin-ai-integration[bot] wants to merge 104 commits into
Open
Complete .NET Framework 4.7.2 → Java 21 / Spring Boot 3.5 Migration — eShopLegacyMVC#155devin-ai-integration[bot] wants to merge 104 commits into
devin-ai-integration[bot] wants to merge 104 commits into
Conversation
- Create Spring Boot 3.5.0 project scaffold under eShopLegacyMVC-SpringBoot/ - Configure pom.xml with Java 21, spring-boot-starter-parent 3.5.0 - Add starters: web, data-jpa, thymeleaf, validation, actuator - Add Flyway (core + sqlserver), mssql-jdbc, jackson-databind - Add WebJars: bootstrap 4.1.3, jquery 3.3.1, popper.js, font-awesome, jquery-validation - Add test dependencies: spring-boot-starter-test, spring-security-test, h2 - Add micrometer-registry-prometheus, thymeleaf-layout-dialect - Create CatalogApplication main class and CatalogApplicationTests - Add minimal application.yml for context loading - Generate Maven Wrapper (mvnw/mvnw.cmd) - Add .gitignore for build artifacts
- Replace minimal application.yml with full config (server, JPA, Thymeleaf, Actuator) - Add application-dev.yml: H2 in-memory, debug logging, Flyway disabled - Add application-mock.yml: H2 in-memory, mock data mode, Flyway disabled - Add application-prod.yml: SQL Server with env var placeholders, Flyway enabled - Add logback-spring.xml with profile-specific logging (ported from log4Net.xml) - Add AppProperties config class for app.use-mock-data and app.use-customization-data - Add db/migration/.gitkeep for future Flyway migrations
Copy application-specific CSS, images, product catalog pics, and favicon from the .NET source project into the Spring Boot static resources directory. Assets copied: - CSS: Site.css, base.css, custom.css - Images: brand.png, brand_dark.png, main_banner.png, main_footer_text.png - Pics: 1.png through 12.png and dummy.png (product catalog images) - favicon.ico No vendor/third-party files copied (bootstrap, jquery, etc. come from WebJars).
… epic-0/project-scaffolding
…ct-scaffolding Epic 0: Initialize Spring Boot 3.5 project scaffold
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add JsonSerializationUtil with serializeToJson/deserializeFromJson methods supporting both byte[] and InputStream overloads. Uses Jackson ObjectMapper for safe JSON serialization, replacing the legacy .NET BinaryFormatter approach. Includes comprehensive unit tests verifying round-trip serialization, error handling, and null field support. Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Add CatalogItem JPA entity mapped to 'Catalog' table - @id without @GeneratedValue (HiLo sequence managed externally) - Jakarta Validation: @NotNull/@SiZe(max=50) on name, @DecimalMin/@DecimalMax on price, @Min/@max on stock fields - BigDecimal for Price with @column(precision=18, scale=2) - @manytoone relationships to CatalogBrand and CatalogType with @joincolumn - PictureUri marked @transient (not persisted) - Default PictureFileName = 'dummy.png' - Add stub CatalogBrand and CatalogType entities for compilation Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…d-library Epic 4: Shared Library Migration — JSON Serialization
…n-entities Epic 1: Domain Entities + Validation
- Add CatalogItemHiLoGenerator as @component in config package - Thread-safe sequence retrieval using ReentrantLock - Uses JdbcTemplate to query SQL Server catalog_hilo sequence - Preserves HiLo increment of 10 from .NET source - Injectable via constructor injection
…rand, and CatalogType - CatalogItemRepository extends JpaRepository with JOIN FETCH query for eager loading - CatalogItemRepository includes @EntityGraph-annotated findAll(Pageable) for pagination - CatalogBrandRepository extends JpaRepository<CatalogBrand, Integer> - CatalogTypeRepository extends JpaRepository<CatalogType, Integer> - All repositories in com.eshop.catalog.repository package
- Add DataInitializer (ApplicationRunner) that reads CSV files when useCustomizationData is enabled via AppProperties - CSV parsing handles: header row skipping, quoted values, empty lines, regex split for comma-inside-quotes - CatalogItems CSV resolves CatalogType/CatalogBrand by name lookup - Handles optional columns (availablestock, restockthreshold, maxstockthreshold, onreorder) - Add repository interfaces for CatalogType, CatalogBrand, CatalogItem - Add sample CSV data files matching PreconfiguredData
Create V1__create_schema.sql with: - CatalogType table (Id IDENTITY, Type nvarchar(100)) - CatalogBrand table (Id IDENTITY, Brand nvarchar(100)) - Catalog table with foreign keys to CatalogType and CatalogBrand - HiLo sequences (catalog_hilo, catalog_brand_hilo, catalog_type_hilo) each starting at 100 with increment 10 - Remove .gitkeep placeholder
CatalogItem uses @id without @GeneratedValue, so explicitly assign sequential IDs (using the 1-based row index) to avoid duplicate primary key violations.
AvailableStock, RestockThreshold, MaxStockThreshold, and OnReorder are mapped to Java primitives (int, boolean) which cannot represent null. The original .NET entity also uses non-nullable value types. Add NOT NULL DEFAULT 0 to match both source and target entity models.
Check repository count before inserting CSV data. If data already exists, skip seeding to avoid duplicate rows in persistent databases.
…to epic-2/data-access
…nto epic-2/data-access
…pic-2/data-access
… CatalogItemRepository conflict)
…access Epic 2: Data Access Layer
…pository query - Create PaginatedItemsDto record in dto/ package for paginated responses - Add findByIdWithBrandAndType query to CatalogItemRepository - Create CatalogService interface with CRUD and pagination methods - Create CatalogServiceImpl with @service @Profile(!mock) @transactional on writes - Class-level @transactional(readOnly=true), method-level @transactional on mutations
…edData, and PaginatedItemsDto - CatalogService: interface defining CRUD + paginated query contract - CatalogServiceMock: @service @Profile("mock") with in-memory ConcurrentHashMap storage - PreconfiguredData: utility providing seed catalog items, brands, and types - PaginatedItemsDto: Java record for paginated response data
…ordering Edit test now targets item 5 (Roslyn Red Sheet) instead of item 1. Delete test now targets item 12 (Prism White TShirt) instead of item 3. This avoids shared-state conflicts with read-only tests that assert on item 1's original name.
…H2 console - Add @ResponseStatus annotations and HttpServletResponse for proper HTTP status codes in GlobalExceptionHandler - Replace CookieCsrfTokenRepository.withHttpOnlyFalse() with new CookieCsrfTokenRepository() (HttpOnly=true) - Exempt /h2-console/** from CSRF and add X-Frame-Options: SAMEORIGIN for H2 console iframe support
…service-tests' into epic-7/testing
…gration-tests' into epic-7/testing
…to epic-8/deployment
Replace incorrect .param() calls (catalogBrand/catalogType entity fields) with .flashAttr() passing a fully-populated CatalogItem. This correctly bypasses data binding and tests the controller validation logic directly, matching how the actual Thymeleaf forms submit catalogBrandId/catalogTypeId.
…to epic-6/cross-cutting
…er' into epic-6/cross-cutting
…rf' into epic-6/cross-cutting
… into epic-6/cross-cutting
…st-controller-tests' into epic-7/testing
…ption status codes The catch-all @ExceptionHandler(Exception.class) was swallowing Spring MVC framework exceptions (405, 415, 400, etc.) and returning 500 for all of them. Extending ResponseEntityExceptionHandler ensures framework exceptions are handled with their correct HTTP status codes before falling through to the catch-all.
…-cutting Epic 6: Cross-Cutting Concerns
…yment Epic 8: Deployment & Cutover
Epic 7: Testing & Validation
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…lidation Devin Review correctly identified that create/edit form submissions always failed validation because @Valid runs before entity references (catalogBrand, catalogType) are resolved from the submitted IDs. Fix: remove @Valid, add resolveEntityReferences() to look up brand/type entities from their IDs via the service before manual validation. Integration tests now properly assert 302 redirect on success.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full migration of the eShopLegacyMVC catalog application from .NET Framework 4.7.2 (ASP.NET MVC 5, Entity Framework 6) to Java 21 / Spring Boot 3.5.0 with Spring Data JPA, Thymeleaf, and WebJars.
Migration scope: 39 .NET source files → 98 new Java/config/template files (6,556 lines) across 9 epics, 40 tickets, executed in 7 waves via 40+ parallel child Devin sessions.
Architecture
Epic Breakdown
Test Results
Quality Gates — All PASS
mvn clean compile: 31 source files, BUILD SUCCESSmvn test: 104/104 pass/actuator/health: UP (db, diskSpace, ping, ssl)See
eShopLegacyMVC-SpringBoot/MIGRATION_TEST_REPORT.mdfor the full test report andeShopLegacyMVC-SpringBoot/WAVE_PROGRESS_REPORT.mdfor per-wave validation history.Review & Testing Checklist for Human
cd eShopLegacyMVC-SpringBoot && ./mvnw clean test— should show 104 tests passing./mvnw spring-boot:run -Dspring-boot.run.profiles=mockand browse http://localhost:8080 — verify catalog listing, pagination, CRUD operationscurl http://localhost:8080/api/brandsshould return 5 brandssrc/main/resources/db/migration/for schema correctnessNotes
devprofile with H2 or configure SQL Server.Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/d7e35cc841ed4d5ab24adbb4685dc208
Requested by: @mbatchelor81