Chapter 2: Jakarta vs Javax Persistence
Introduction
If you've ever looked at Spring Boot code online, you've probably seen two different types of imports:
import javax.persistence.*; // Old
import jakarta.persistence.*; // New
Question: What is the difference? Which one should you use?
Short answer: Use Jakarta (jakarta.persistence) for all your new projects with Spring Boot 3.x+.
History: Java EE → Jakarta EE
The Transition
Before 2019: Java EE (packages javax.*)
Oracle owned Java EE (Java Enterprise Edition), which included JPA (Java Persistence API).
After 2019: Jakarta EE (packages jakarta.*)
Oracle transferred Java EE to the Eclipse Foundation, which renamed it Jakarta EE.
Legal issue: Oracle held the rights to the name javax, so Eclipse had to create a new namespace: jakarta.
Analogy
Imagine a company (Oracle) sells its division (Java EE) to another company (Eclipse Foundation).
Oracle says: "You can have the product, but not the logo and the name."
Eclipse replies: "OK, we'll rename it Jakarta EE and change all the packages."
Result:
- Same functionality
- New package name
- New beginning
Comparison Javax vs Jakarta
Comparison Table
| Aspect | Javax | Jakarta |
|---|---|---|
| Package | javax.persistence.* | jakarta.persistence.* |
| Spring Boot | 2.x (up to 2.7.x) | 3.x+ |
| Java | Java 8+ | Java 17+ |
| Status | Obsolete | Current and recommended |
| Support | Maintenance only | Active development |
| Businesses | Old applications | New applications |
Spring Boot Versions
| Spring Boot Version | JPA Package | Java Version |
|---|---|---|
| 2.0 - 2.7.x | javax.persistence | Java 8+ |
| 3.0+ | jakarta.persistence | Java 17+ |
Simple rule:
- Spring Boot 2.x →
javax - Spring Boot 3.x →
jakarta
Migration: Javax → Jakarta
Complete Example
Before (Javax - Spring Boot 2.x)
File: model/Product.java
package com.example.demo.model;
import javax.persistence.*;
import javax.validation.constraints.*;
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Size(min = 3, max = 100)
private String name;
@Min(0)
private Double price;
// Constructors, getters, setters
}
After (Jakarta - Spring Boot 3.x)
File: model/Product.java
package com.example.demo.model;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Size(min = 3, max = 100)
private String name;
@Min(0)
private Double price;
// Constructors, getters, setters
}
Change: Replace all javax with jakarta.
Affected Annotations
Here are the annotations you will need to migrate:
JPA (Persistence)
// Javax
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.JoinColumn;
// Jakarta
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Column;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.JoinColumn;
Validation
// Javax
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.Email;
// Jakarta
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Email;
Transactions
// Javax
import javax.transaction.Transactional;
// Jakarta
import jakarta.transaction.Transactional;
Note: Spring also provides @Transactional which remains the same:
import org.springframework.transaction.annotation.Transactional;
Automatic Migration in VS Code
Method 1: Find and Replace
Step 1: Open global search (Ctrl+Shift+F or Cmd+Shift+F)
Step 2: Enable Regex mode (icon .*)
Step 3: Search for:
javax\.persistence
Step 4: Replace with:
jakarta.persistence
Step 5: Do the same for:
javax\.validation
Replace with:
jakarta.validation
Method 2: PowerShell Script (Windows)
# Navigate to your project
cd C:\path\to\your\project
# Replace javax.persistence with jakarta.persistence
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'javax\.persistence', 'jakarta.persistence' | Set-Content $_.FullName
}
# Replace javax.validation with jakarta.validation
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'javax\.validation', 'jakarta.validation' | Set-Content $_.FullName
}
Method 3: Bash Script (Linux/macOS)
# Navigate to your project
cd /path/to/your/project
# Replace javax.persistence with jakarta.persistence
find . -name "*.java" -type f -exec sed -i '' 's/javax\.persistence/jakarta.persistence/g' {} +
# Replace javax.validation with jakarta.validation
find . -name "*.java" -type f -exec sed -i '' 's/javax\.validation/jakarta.validation/g' {} +
Compatibility with Spring Boot
Spring Boot 2.x (Javax)
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
Java: 8, 11, or 17
Imports: javax.persistence.*
Spring Boot 3.x (Jakarta)
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
Java: 17+ (required)
Imports: jakarta.persistence.*
Troubleshooting Common Issues
Error 1: ClassNotFoundException
Error:
java.lang.ClassNotFoundException: javax.persistence.Entity
Cause: You are using Spring Boot 3.x with javax imports.
Solution: Replace all javax with jakarta.
Error 2: NoClassDefFoundError
Error:
java.lang.NoClassDefFoundError: jakarta/persistence/Entity
Cause: You are using Spring Boot 2.x with jakarta imports.
Solutions:
Option 1: Upgrade to Spring Boot 3.x
Option 2: Revert to javax imports
Error 3: Incorrect Java Version
Error:
invalid target release: 17
Cause: Spring Boot 3.x requires Java 17+, but you are using Java 11 or lower.
Solution: Install Java 17+ and update pom.xml:
<properties>
<java.version>17</java.version>
</properties>
Which Version to Choose?
For New Projects
Use Jakarta (Spring Boot 3.x+)
Advantages:
- ✅ Latest Spring features
- ✅ Active support
- ✅ Better performance
- ✅ Up-to-date security
- ✅ Future-proof
Configuration:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
import jakarta.persistence.*;
For Existing Projects
If Spring Boot 2.x:
- Stay on
javaxfor now - Plan a migration to Spring Boot 3.x
If Spring Boot 3.x:
- Migrate immediately to
jakarta
Migration Checklist
Before Migrating
- Check Spring Boot version
- Check Java version (17+ required)
- Backup your code (Git commit)
- List all third-party dependencies
Migration
- Update
pom.xmlto Spring Boot 3.x - Update Java to 17+
- Replace
javax.persistencewithjakarta.persistence - Replace
javax.validationwithjakarta.validation - Replace
javax.transactionwithjakarta.transaction - Update third-party dependencies (if necessary)
After Migration
- Compile the project (
mvn clean compile) - Run tests (
mvn test) - Start the application (
mvn spring-boot:run) - Test all functionalities
- Check logs for warnings
Summary
Key Points
✅ Jakarta = New standard (Spring Boot 3.x+, Java 17+)
✅ Javax = Old standard (Spring Boot 2.x, Java 8+)
✅ Migration = Simple (Find/Replace)
✅ Always use Jakarta for new projects
Final Analogy
Javax = Windows XP 💾
- Still works
- But no more support
Jakarta = Windows 11 🖥️
- Modern
- Actively supported
- Recommended for the future
Next Step
Now that you understand Jakarta vs Javax, let's move on to Chapter 3 to master Hibernate and DDL Strategies.