Migrate UserFront from Java 8 + Spring Boot 1.5.4 to Java 17 + Spring Boot 3.1.5#7
Conversation
… Boot 3.1.5 - Update pom.xml: Spring Boot 3.1.5, Java 17, mysql-connector-j - Migrate javax.* to jakarta.* namespace in all domain/config files - Refactor SecurityConfig: remove WebSecurityConfigurerAdapter, use SecurityFilterChain bean - Replace @EnableGlobalMethodSecurity with @EnableMethodSecurity - Update application.properties: remove deprecated HikariCP props, use MySQLDialect - Change GenerationType.AUTO to GenerationType.IDENTITY in all entities - Fix Spring Data 3.x API: findOne() -> findById().orElse(null) - Migrate test class from JUnit 4 to JUnit 5 - Apply Java 17 var type inference across controllers, services, and domain Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
🤖 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:
|
| var appointment = findAppointment(id); | ||
| appointment.setConfirmed(true); | ||
| appointmentDao.save(appointment); |
There was a problem hiding this comment.
🔴 NullPointerException in confirmAppointment when appointment ID is not found
The findAppointment method at AppointmentServiceImpl.java:27 was migrated from findOne(id) to findById(id).orElse(null), which returns null when the appointment doesn't exist. The confirmAppointment method at line 31-33 calls findAppointment(id) and immediately dereferences the result (appointment.setConfirmed(true)) without a null check, causing a NullPointerException. This is reachable from the AppointmentResource.confirmAppointment REST endpoint (AppointmentResource.java:30-31), which takes the id from a path variable. When an admin sends a request with a non-existent appointment ID, the server will crash with an unhandled NPE.
| var appointment = findAppointment(id); | |
| appointment.setConfirmed(true); | |
| appointmentDao.save(appointment); | |
| var appointment = findAppointment(id); | |
| if (appointment == null) { | |
| throw new IllegalArgumentException("Appointment not found with id: " + id); | |
| } | |
| appointment.setConfirmed(true); | |
| appointmentDao.save(appointment); |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Fixed in dbf52b8 — added null check with IllegalArgumentException as suggested. Good catch on this regression introduced by the findOne() → findById().orElse(null) migration.
…word, and multi-servlet security - Add @lazy to break circular dependency between UserServiceImpl, AccountServiceImpl, and TransactionServiceImpl (prohibited by default in Spring Boot 3.x) - Add @table(name="users") to User entity to avoid SQL reserved keyword conflict - Use explicit AntPathRequestMatcher in SecurityConfig to resolve multi-servlet ambiguity - Add H2 database dependency for local testing without MySQL Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
- Add null guard in AppointmentServiceImpl.confirmAppointment() to prevent NPE when appointment ID doesn't exist (findById returns Optional.empty -> orElse(null)) - Add application-h2.properties for local testing with H2 in-memory database Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
End-to-End Test Results — Spring Boot 3 MigrationRan the app locally with H2 in-memory database ( Session: https://app.devin.ai/sessions/b0736040b00144189c0396a99781fea9 Escalation
Test Results
Screenshots
Login redirect issue detailAfter form submission to |
Spring Security 6.x's defaultSuccessUrl without alwaysUse=true redirects to saved requests instead of the configured URL, causing a status 999 error page in the browser. Setting alwaysUse=true forces redirect to /userFront after successful authentication. Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
End-to-End Test Results — Spring Boot 3 Migration (Updated)Ran the app locally with H2 in-memory database ( Session: https://app.devin.ai/sessions/b0736040b00144189c0396a99781fea9 Bug Found & Fixed During TestingLogin redirect: initial testing revealed
Test Results
|
Summary
Comprehensive migration of the
UserFront/module from Java 8 + Spring Boot 1.5.4 to Java 17 + Spring Boot 3.1.5, covering all 8 migration sections plus runtime fixes discovered during testing:spring-boot-starter-parentto 3.1.5,java.versionto 17, renamedmysql-connector-java→com.mysql:mysql-connector-j, added H2 for local testingjavax.persistence.*andjavax.servlet.*imports tojakarta.*across 10 filesWebSecurityConfigurerAdapter, replaced with@Bean SecurityFilterChain. Used explicitAntPathRequestMatcherinstances to avoid multi-servlet ambiguity. Replaced@EnableGlobalMethodSecuritywith@EnableMethodSecurity. SetdefaultSuccessUrl("/userFront", true)to fix login redirect in Spring Security 6.x.testWhileIdle/validationQuery, updated Hibernate dialect toMySQLDialectGenerationType.AUTO→GenerationType.IDENTITYin 8 entity classesvarlocal variable type inference across controllers/services/domainfindOne()→findById().orElse(null)with null guard inconfirmAppointment()@Lazyto break circular bean dependencies (prohibited by default in Spring Boot 3.x)@Table(name = "users")on User entity to avoid SQL reserved keyword conflictdata.sqlseed file for H2 role initializationmvn clean compilepasses; app starts and runs E2E with H2 profile28 files changed.
Review & Testing Checklist for Human
mvn spring-boot:run -Dspring-boot.run.profiles=h2and verify it boots without errors/signup, create a user, then login at/index— verifies SecurityFilterChain + BCrypt + UserDetailsService + login redirect/userFrontdashboard — verifies JPA entities with GenerationType.IDENTITY and @lazy dependency resolutionmvn spring-boot:runwithout H2 profile) against anonlinebankingdatabase to verify production configNotes
UserServiceImpl↔AccountServiceImpl↔TransactionServiceImplwas hidden in Spring Boot 1.5.x (which allowed circular refs by default). Fixed with@Lazyinjection.Userentity needed@Table(name = "users")becauseuseris a reserved SQL keyword in H2 and several other databases.SecurityConfig.requestMatchers()needed explicitAntPathRequestMatcherinstances because H2 console registers a second servlet, causing Spring Security's auto-detection to fail.defaultSuccessUrl("/userFront", true)— withoutalwaysUse=true, Spring Security 6.x follows stale saved requests instead of the configured URL.data.sqlto seed ROLE_USER and ROLE_ADMIN since the in-memory database starts empty.Link to Devin session: https://app.devin.ai/sessions/b0736040b00144189c0396a99781fea9
Requested by: @stephencornwell
Devin Review