Jakarta EE 12 M2: Entering the Data Age of Enterprise Java
Jakarta EE 12 aligns repositories, restrictions, queries, ORM, and NoSQL into a unified data model, making domain-centric data access a first-class platform feature.
Join the DZone community and get the full member experience.
Join For FreeEvery major Jakarta EE release tends to have a defining theme. Jakarta EE 11 was about modernization: a new baseline with Java 17, forward compatibility with Java 21, and a decisive cleanup of long-standing technical debt. Jakarta EE 12 builds directly on that momentum, but its direction is different. This release is less about removing the past and more about aligning the future.
Jakarta EE 12 is best understood as the Data Age of enterprise Java.
This is the release where persistence, querying, repositories, NoSQL, configuration, and even AI-related concerns begin to converge into a more coherent platform story. With the second milestone (M2) scheduled for the end of January 2026, Jakarta EE 12 is already showing how that alignment is taking shape.
From Jakarta EE 11 to Jakarta EE 12: Why This Release Matters
After the release of Jakarta EE 11 in June 2025, work on Jakarta EE 12 moved quickly. The goal was never to introduce a disruptive rewrite, but to improve integration, consistency, configuration, and developer productivity across the platform.
Jakarta EE 12 follows a familiar milestone-based process: early milestones for experimentation and feedback, followed by refinement milestones, culminating in the final platform vote by the Jakarta EE Steering Committee. Milestone 2 is particularly important because it is where architectural direction becomes visible and individual specifications start to align.
At a platform level, Jakarta EE 12 reflects several irreversible shifts:
- Java 21 becomes the baseline, with support for Java 25
- The deprecated Java SecurityManager has been fully removed
- Ambiguous and legacy APIs are cleaned up
- The platform explicitly prepares for modern protocols such as HTTP/3
These changes form the foundation on which the rest of the platform evolves.

CDI 5.0: Toward More Predictable Application Startup
Dependency injection remains the backbone of Jakarta EE applications, and Jakarta CDI 5.0 continues the trend of simplifying and clarifying the programming model.
One recurring request from developers is better control over application startup behavior, especially for components that must be initialized eagerly. While CDI 5.0 does not yet standardize eager initialization semantics, the specification and ecosystem increasingly encourage explicit patterns for it.
A common, future-facing approach looks like this:
@ApplicationScoped
@Eager // conceptual example – not yet standardized
public class CacheInitializer {
@Inject
DataSource dataSource;
public void init() {
// warm up cache, validate connections, preload data
}
}
This pattern reflects where CDI is heading: explicit lifecycle control, predictable startup, and better alignment with modern deployment environments such as Kubernetes and serverless platforms.
Jakarta MVC 3.1: Simplicity for Web-Facing Applications
While REST dominates back-end communication, traditional MVC still plays an important role in web applications. Jakarta MVC 3.1 continues to offer a clean, minimal programming model for server-side rendered applications.
A simple controller illustrates the philosophy:
@Controller
@Path("/hello")
public class HelloController {
@GET
public String hello() {
return "hello.jsp";
}
}
Jakarta MVC deliberately avoids complexity. It integrates cleanly with CDI, Jakarta REST, and the broader platform, making it a practical choice for applications that require server-side views without adopting heavyweight frameworks.
The Data Age: Persistence, Repositories, and Query Alignment
Jakarta EE 12 earns the title of the Data Age not because it introduces yet another persistence abstraction, but because it finally aligns several long-evolving ones into a coherent model. Instead of forcing developers into a single way to access data, the platform now embraces multiple styles — repository-centric, ORM-centric, and query-centric — while ensuring they fit together cleanly.
At the repository level, Jakarta Data 1.1 continues to define how applications express intent when accessing data. But Jakarta EE 12 shifts attention away from basic CRUD — which was already stable in Jakarta EE 11 — and toward how repositories express queries dynamically and portably. This is where restrictions become central.
Restrictions provide a fluent, type-safe way to construct queries programmatically, without embedding query strings or leaking database semantics into application code. They are especially important in Jakarta EE 12 because they sit precisely at the intersection of repositories, querying, and database portability.
Given a repository like this:
@Repository
public interface Countries extends CrudRepository<Country, String> {
@Find
List<Country> filter(Restriction<Country> restriction);
}
A restriction represents a reusable predicate over the domain model. Simple queries remain expressive without becoming opaque:
List<Country> european =
countries.filter(
Restrict.all(
_Country.code.in("FI", "FR", "DE", "IT")
)
);
More complex queries can be composed fluently, combining multiple conditions with clear semantics:
List<Country> result =
countries.filter(
Restrict.all(
_Country.code.notNull(),
_Country.code.in("FI", "FR", "GR"),
_Country.code.notEqualTo("FR")
)
);
Logical alternatives are just as explicit:
List<Country> americasOrAsia =
countries.filter(
Restrict.any(
_Country.code.equalTo("CO"),
_Country.code.equalTo("MY")
)
);
What matters here is not syntactic convenience, but semantic stability. These restrictions mean the same thing whether the underlying store is relational or NoSQL. Jakarta EE 12 leans into this model because it captures the shared behavior of persistence systems, without flattening their differences.
This repository-level querying model aligns naturally with Jakarta Query, which becomes a first-class platform specification in Jakarta EE 12. Jakarta Query defines the Jakarta Common Query Language (JCQL), extracting the common subset of JPQL and Jakarta Data Query into a single place. String-based queries and restriction-based queries are no longer competing ideas; they are complementary tools within the same conceptual framework.
On the ORM side, Jakarta Persistence 4.0 evolves independently while remaining compatible. As explained by Gavin King in his Jakarta Persistence 4.0 milestone article, the focus is on clarity, modern Java usage, and the provision of alternative programming models — not on absorbing repository semantics.
One example of this is the new EntityAgent, which allows direct, stateless interaction with the database:
var book = factory.callInTransaction(EntityAgent.class, agent -> {
return agent.get(Book.class, isbn);
});
book.setTitle("Hibernate in Action");
factory.runInTransaction(EntityAgent.class, agent -> {
agent.update(book);
});
This model does not replace repositories. Instead, it exists alongside them, serving developers who prefer explicit database interaction over persistence contexts. Jakarta EE 12 makes room for both approaches, without forcing either.
Query alignment continues with improvements in projection and typing. With Jakarta Persistence 4.0 and Jakarta Query, record-based projections no longer require special syntax:
record Summary(String title, String isbn, LocalDate date) {}
var summaries =
agent.createQuery("""
select title, isbn, pubDate
from Book
where title like ?1
""")
.ofType(Summary.class)
.setParameter(1, "%Jakarta%")
.getResultList();
Meanwhile, Jakarta NoSQL 1.1 adopts the same query concepts, exposing a Query API that mirrors the relational model while remaining suitable for non-relational databases:
Query query = Query.of("where code = :code")
.bind("code", "FI");
Optional<Country> country =
query.singleResult(Country.class);
Results can be consumed uniformly as Optional, List, or Stream, reinforcing the idea that query semantics belong to the platform, not to individual storage technologies.
Taken together, these changes explain why Jakarta EE 12 is best described as the Data Age. The platform no longer treats persistence as a single abstraction centered on tables or entities. Instead, it provides a layered and aligned model:
- Jakarta Data expresses intent through repositories and restrictions
- Jakarta Query defines shared query semantics
- Jakarta Persistence provides relational lifecycle and ORM control
- Jakarta NoSQL brings non-relational stores into the same conceptual space
The result is not simplification by removing options, but simplification by alignment. Jakarta EE 12 gives developers the freedom to choose how they work with data — while ensuring those choices remain consistent, portable, and predictable across the platform.
Jakarta EE Meets AI: The Rise of Agentic Applications
Another notable addition to Jakarta EE 12 is the emergence of Jakarta Agentic AI, a new specification that has passed its creation review. Its goal is to define vendor-neutral APIs for building, deploying, and operating AI agents within Jakarta EE runtimes.
This is not about embedding AI frameworks directly into the platform. Instead, it provides structural concepts — agents, triggers, decisions, actions, and outcomes — that integrate naturally with CDI, persistence, and enterprise services.
A simplified example illustrates the intent:
@Agent
public class FraudDetectionAgent {
@Inject
LargeLanguageModel model;
@Inject
EntityManager entityManager;
@Trigger
void processTransaction(@Valid BankTransaction transaction) {
// decide whether this transaction should be evaluated
}
@Decision
Result checkFraud(BankTransaction transaction) {
String output = model.query(
"Is this a fraudulent transaction?", transaction);
return new Result(isFraud(output));
}
@Action
void handleFraud(Fraud fraud, BankTransaction transaction) {
// notify systems and users
}
@Outcome
void finalizeTransaction(BankTransaction transaction) {
// persist result
}
}
The significance here is architectural. Jakarta EE is acknowledging that AI-driven workflows are becoming a first-class concern in enterprise systems — and that they must integrate cleanly with data, transactions, and security.
Conclusion
Jakarta EE 12 is not defined by a single headline feature. Its importance lies in alignment.
- Data access converges through Jakarta Data, Persistence, NoSQL, and Query
- Configuration, integration, and cleanup improve developer productivity
- CDI and MVC continue to evolve without unnecessary reinvention
- AI enters the platform in a structured, enterprise-ready way
Calling Jakarta EE 12 the Data Age is not marketing — it reflects a deliberate architectural shift. Enterprise Java is no longer optimizing for a single persistence model or programming style. It is optimizing for coherence across diversity.
Milestone 2 makes that direction visible. The final release will make it real.
Opinions expressed by DZone contributors are their own.
Comments