Summary
A developer with legacy Java experience (SCJP, circa 2013) asked for recommendations on the data layer for a new Jakarta EE web application, specifically comparing Spring Boot/Spring Data JPA versus “straight” Jakarta EE. The developer explicitly required a traditional WAR deployment to a standalone server (no embedded servers) and needed standard CRUD operations via a repository pattern. The core debate centered on whether Spring is still the industry standard or if pure Jakarta EE is now a viable, lighter-weight alternative for a “reg war” (regular WAR) architecture.
Root Cause
The root cause of the confusion is the massive paradigm shift in the Java ecosystem between 2013 (the era of heavy Spring XML and Java EE 6/7) and the modern landscape ( Jakarta EE 9/10 and Spring Boot 3). The developer is attempting to apply a 2013 mental model to 2024 tools, specifically misunderstanding the complexity of “modern” Spring (which defaults to embedded servers and reactive programming) versus the stability of Jakarta EE (the rebranded Java EE).
Why This Happens in Real Systems
- Ecosystem Evolution: The Java ecosystem split. Spring Boot became the default for microservices and rapid development, often hiding the “WAR” deployment model. Jakarta EE continued the tradition of standard monolithic WARs but rebranded from
javaxtojakartanamespaces, causing upgrade friction. - Deployment Mismatch: Modern tutorials almost exclusively push Spring Boot with embedded Tomcat. Developers requiring traditional WAR deployment to external servers (WebLogic, Tomcat, JBoss) often struggle to find documentation that explicitly disables Spring’s embedded server defaults.
- Repository Abstraction: Both Spring Data JPA and Jakarta EE (via
EntityManager/Criteria API) solve the same problem, but Spring Data offers significant boilerplate reduction (automatic CRUD implementation) that “straight” Jakarta EE requires you to write manually or acquire via external libraries.
Real-World Impact
- Over-Engineering vs. Bloat:
- Choosing Spring Boot without wanting its embedded server features introduces unnecessary abstraction layers and dependency weight for a simple WAR.
- Choosing Straight Jakarta EE often results in writing verbose, repetitive boilerplate code (DAOs/Repositories) that Spring Data generates automatically, slowing down development velocity.
- Vendor Lock-in vs. Standardization:
- Spring is a framework, not a standard. While ubiquitous, it ties the architecture to Pivotal/VMware patterns.
- Jakarta EE is a standard. Switching vendors (e.g., from Tomcat to WildFly) is theoretically easier, but the ecosystem of libraries is smaller.
- Onboarding Friction: Using “pure” Jakarta EE often forces new hires to learn non-standard, project-specific repository implementations rather than the Spring Data patterns they likely know from other jobs.
Example or Code
If choosing Straight Jakarta EE (JPA) for a “Reg War,” you must manually implement the DAO/Repository pattern using the EntityManager. You do not get auto-generated repositories.
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import java.util.List;
@Transactional
public class UserRepository {
@PersistenceContext
private EntityManager em;
public User findById(Long id) {
return em.find(User.class, id);
}
public List findAll() {
return em.createQuery("SELECT u FROM User u", User.class).getResultList();
}
public void create(User user) {
em.persist(user);
}
public void update(User user) {
em.merge(user);
}
public void delete(Long id) {
User user = em.find(User.class, id);
if (user != null) {
em.remove(user);
}
}
}
How Senior Engineers Fix It
- Contextual Decision Making: A senior engineer analyzes the lifespan of the project.
- If this is a short-lived, internal tool or a microservice (even if the developer denies it now), Spring Boot is selected. We configure the
pom.xmlto exclude the embedded Tomcat starter but keep Spring Data JPA for the repository abstraction. - If this is a legacy corporate monolith requiring strict adherence to vendor specs (Oracle WebLogic, IBM WebSphere), Jakarta EE is the correct, conservative choice.
- If this is a short-lived, internal tool or a microservice (even if the developer denies it now), Spring Boot is selected. We configure the
- Pragmatism over Purity: We recommend Spring Boot + Spring Data JPA even for a WAR deployment. The “Spring Tax” is negligible compared to the productivity gain of PagingAndSortingRepository.
- Build Configuration: To satisfy the “Reg WAR” requirement while using Spring, we specifically exclude the web starter:
org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat
Why Juniors Miss It
- Focus on “Magic”: Juniors often look at Spring Boot as a black box. They don’t understand that the repository works because of JPA underneath. They think Spring is the database layer, not an abstraction over it.
- Ignoring the Deployment Descriptor: Juniors are trained to run
main()methods. They forget that a WAR requires aweb.xml(orWebApplicationInitializerin modern Spring) and a servlet container scope. - “Standard” vs. “Popular”: Juniors often assume “Standard” (Jakarta EE) is the safe bet, not realizing that Spring is the de facto standard in the job market. They underestimate the sheer volume of boilerplate required to replace Spring Data’s
save()andfindAll()methods.