💻 Coding
Spring Boot 2.7 to 3.x Migration Planner: Java 17 Baseline, javax to jakarta Imports, Spring Security 6 SecurityFilterChain and requestMatchers, Hibernate 6 Sequence Naming, Trailing Slash Matching, properties-migrator, and OpenRewrite
Upgrade a Spring Boot 2.7 service to 3.x in safe steps: move to Java 17, swap javax imports for jakarta without touching Java SE packages, replace WebSecurityConfigurerAdapter with a SecurityFilterChain bean, handle Hibernate 6 sequence and query changes, decide what to do about trailing slash URLs, find renamed properties, and let OpenRewrite do the mechanical edits.
0Reviews
Prompt
Act as a senior Java backend engineer who has migrated dozens of Spring Boot 2.7 services to 3.x, runs OpenRewrite recipes before touching code by hand, and has seen a release fail because Hibernate 6 started looking for a different sequence name. Inputs: - Build file with Spring Boot, Java, and third party dependency versions (pom.xml or build.gradle): [BuildFile] - Current Spring Security configuration code: [SecurityConfig] - JPA usage: ID generation strategies, database, native queries, custom types: [JpaUsage] - Web endpoints and clients that call them, including any that use trailing slashes: [WebEndpoints] - Integrations: tracing, API docs, caching, messaging libraries: [Integrations] - Target Boot version and test setup: [TargetAndTests] - Output format: [Format] Generate: 1. A phased plan: upgrade to the latest 2.7.x and clear deprecation warnings first, then Java 17 on 2.7, then Boot 3.x. Mark the target from TargetAndTests and note that later 3.x lines and Boot 4 may change more; check your version notes. 2. An OpenRewrite step: the rewrite-spring recipe for Boot 3 (for example org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0 or a later 3.x recipe) run with the Maven or Gradle plugin on a branch, then a review of the diff. 3. A javax to jakarta map: javax.persistence, javax.servlet, javax.validation, javax.annotation (where Jakarta), and javax.transaction move to jakarta.*; Java SE packages such as javax.sql and javax.crypto stay as they are. 4. A dependency table from BuildFile and Integrations: each library, its Jakarta compatible version or replacement (for example springfox to springdoc-openapi 2.x, Spring Cloud Sleuth to Micrometer Tracing), and a blocker column. 5. Spring Security 6 rewrite of SecurityConfig: WebSecurityConfigurerAdapter is gone, so expose a SecurityFilterChain bean; authorizeRequests becomes authorizeHttpRequests; antMatchers and mvcMatchers become requestMatchers; @EnableGlobalMethodSecurity becomes @EnableMethodSecurity. Show before and after code. 6. Hibernate 6 checks from JpaUsage: the default sequence naming change for GenerationType.AUTO or SEQUENCE (per entity sequences instead of one shared hibernate_sequence), the legacy naming setting to keep the old behavior during migration, query syntax issues in HQL, and custom @Type mappings. 7. Trailing slash matching: Spring Framework 6 no longer matches /orders/ to /orders by default. From WebEndpoints, list affected clients and pick a fix: update clients, map both paths, or use a URL handler filter where your Framework version provides it. 8. Properties: add spring-boot-properties-migrator at runtime during the migration to log renamed keys (for example spring.redis.* to spring.data.redis.*), then remove it. 9. A test and release checklist: compile, unit and integration tests, security tests for each protected path, a database migration test against a copy of production schema, and a canary release. Constraints: - Base every change on the Inputs; never claim a library version exists without telling the user to confirm it on Maven Central. - Show code in Java. No em dashes.
Instructions
Replace every [bracket] with your details before running. Works on ChatGPT, Claude, and Gemini.
Generated Output
This image was generated using the prompt above.

Examples
Example Input
BuildFile: Maven, spring-boot-starter-parent 2.7.18, Java 11, springfox-boot-starter 3.0.0, spring-cloud-starter-sleuth, spring-boot-starter-data-redis, postgresql driver
SecurityConfig: class SecurityConfig extends WebSecurityConfigurerAdapter; configure(HttpSecurity http) uses http.authorizeRequests().antMatchers("/api/admin/**").hasRole("ADMIN").antMatchers("/api/**").authenticated().and().httpBasic(); @EnableGlobalMethodSecurity(prePostEnabled = true)
JpaUsage: 23 entities with @GeneratedValue(strategy = GenerationType.AUTO) on PostgreSQL; the database has one sequence named hibernate_sequence; Flyway manages the schema
WebEndpoints: the mobile app calls GET /api/orders/ and POST /api/orders/ with trailing slashes; it cannot be updated for 6 weeks
Integrations: Zipkin tracing via Sleuth, Swagger UI via springfox, application.yml has spring.redis.host
TargetAndTests: target Spring Boot 3.5.x; JUnit 5 with Testcontainers for PostgresExample Output
1) PHASES
1. 2.7.18 is the last 2.7 release: fix all deprecation warnings on it.
2. Java 11 to 17 on Boot 2.7.18, release.
3. Boot 3.5.x on a branch (steps 2 to 9), release behind a canary.
Boot 4 exists; plan it as a separate step later. Check your version notes.
2) OPENREWRITE
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run \
-Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE \
-Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5
If that recipe name is not in your rewrite-spring version, use UpgradeSpringBoot_3_0 and bump the parent by hand. Review the diff before committing.
3) JAVAX TO JAKARTA
- javax.persistence.* to jakarta.persistence.* (23 entities)
- javax.validation.* to jakarta.validation.*
- javax.servlet.* to jakarta.servlet.*
- Leave javax.sql.DataSource alone; it is part of Java SE.
4) DEPENDENCIES
| Today | Boot 3 | Blocker |
| springfox-boot-starter 3.0.0 | springdoc-openapi-starter-webmvc-ui 2.x | Yes: springfox has no Jakarta support |
| spring-cloud-starter-sleuth | micrometer-tracing-bridge-brave + zipkin-reporter-brave | Yes: Sleuth ended at 2.7 |
| data-redis | managed by Boot | Property rename only |
Confirm exact versions on Maven Central.
5) SECURITY
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain api(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/**").authenticated())
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
@EnableMethodSecurity turns on prePostEnabled by default.
6) HIBERNATE 6 SEQUENCES
With AUTO on Postgres, Hibernate 6 looks for one sequence per entity (for example orders_seq) with increment 50, not hibernate_sequence. During migration set:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy: legacy
Later, add a Flyway migration that creates per entity sequences starting above current max ids, then drop the setting.
7) TRAILING SLASHES
The app's /api/orders/ calls will 404 on Boot 3. Short term: @RequestMapping({"/api/orders", "/api/orders/"}) on OrderController. Remove the extra path once the app ships its fix in 6 weeks.
8) PROPERTIES
Add spring-boot-properties-migrator (runtime scope) and read the startup log. Expected: spring.redis.host to spring.data.redis.host. Remove the migrator before release.
9) CHECKLIST
[ ] mvn verify green on Java 17
[ ] Testcontainers Postgres test inserts a row in each of the 23 entities
[ ] Security tests: /api/admin/** returns 403 for USER, 200 for ADMIN; /api/** returns 401 when anonymous
[ ] Swagger UI loads at the springdoc path
[ ] Traces show up in Zipkin from Micrometer Tracing
[ ] Canary at 10 percent for a day, watch 404s on /api/orders/