Skip to main content

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​

AspectJavaxJakarta
Packagejavax.persistence.*jakarta.persistence.*
Spring Boot2.x (up to 2.7.x)3.x+
JavaJava 8+Java 17+
StatusObsoleteCurrent and recommended
SupportMaintenance onlyActive development
BusinessesOld applicationsNew applications

Spring Boot Versions​

Spring Boot VersionJPA PackageJava Version
2.0 - 2.7.xjavax.persistenceJava 8+
3.0+jakarta.persistenceJava 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 javax for 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.xml to Spring Boot 3.x
  • Update Java to 17+
  • Replace javax.persistence with jakarta.persistence
  • Replace javax.validation with jakarta.validation
  • Replace javax.transaction with jakarta.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.

➡️ Chapter 3: Hibernate DDL

⬅️ Previous Chapter: PostgreSQL

⬅️ Back to Module 4