Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions content/enterprise/ejb-vs-cdi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"id": 99,
"slug": "ejb-vs-cdi",
"title": "EJB versus CDI",
"category": "enterprise",
"difficulty": "intermediate",
"jdkVersion": "11",
"oldLabel": "Java EE",
"modernLabel": "Jakarta EE 8+",
"oldApproach": "EJB",
"modernApproach": "CDI Bean",
"oldCode": "@Stateless\npublic class OrderEJB {\n @EJB\n private InventoryEJB inventory;\n\n public void placeOrder(Order order) {\n // container-managed transaction\n inventory.reserve(order.getItem());\n }\n}",
"modernCode": "@ApplicationScoped\npublic class OrderService {\n @Inject\n private InventoryService inventory;\n\n @Transactional\n public void placeOrder(Order order) {\n inventory.reserve(order.getItem());\n }\n}",
"summary": "Replace heavyweight EJBs with lightweight CDI beans for dependency injection and transactions.",
"explanation": "CDI (Contexts and Dependency Injection) provides the same dependency injection and transaction management as EJBs, but as plain Java classes with no container-specific interfaces or superclasses. Scopes like @ApplicationScoped and @RequestScoped control lifecycle, and @Transactional replaces mandatory EJB transaction semantics.",
"whyModernWins": [
{
"icon": "🪶",
"title": "Lightweight",
"desc": "CDI beans are plain Java classes with no EJB-specific interfaces or descriptors."
},
{
"icon": "💉",
"title": "Unified injection",
"desc": "@Inject works for every managed bean, JAX-RS resources, and Jakarta EE components alike."
},
{
"icon": "🧪",
"title": "Easy unit testing",
"desc": "Plain classes without EJB proxy overhead are straightforward to instantiate and mock."
}
],
"support": {
"state": "available",
"description": "Widely available since Jakarta EE 8 / Java 11"
},
"prev": "enterprise/servlet-vs-jaxrs",
"next": "enterprise/jdbc-vs-jpa",
"related": [
"enterprise/servlet-vs-jaxrs",
"enterprise/jdbc-vs-jpa",
"language/records-for-data-classes"
],
"docs": [
{
"title": "Jakarta CDI Specification",
"href": "https://jakarta.ee/specifications/cdi/"
},
{
"title": "Jakarta Transactions — @Transactional",
"href": "https://jakarta.ee/specifications/transactions/"
}
]
}
54 changes: 54 additions & 0 deletions content/enterprise/jdbc-vs-jpa.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"id": 100,
"slug": "jdbc-vs-jpa",
"title": "JDBC versus JPA",
"category": "enterprise",
"difficulty": "intermediate",
"jdkVersion": "11",
"oldLabel": "Java EE",
"modernLabel": "Jakarta EE 8+",
"oldApproach": "JDBC",
"modernApproach": "JPA EntityManager",
"oldCode": "String sql = \"SELECT * FROM users WHERE id = ?\";\ntry (Connection con = dataSource.getConnection();\n PreparedStatement ps =\n con.prepareStatement(sql)) {\n ps.setLong(1, id);\n ResultSet rs = ps.executeQuery();\n if (rs.next()) {\n User u = new User();\n u.setId(rs.getLong(\"id\"));\n u.setName(rs.getString(\"name\"));\n }\n}",
"modernCode": "@PersistenceContext\nEntityManager em;\n\npublic User findUser(Long id) {\n return em.find(User.class, id);\n}\n\npublic List<User> findByName(String name) {\n return em.createQuery(\n \"SELECT u FROM User u WHERE u.name = :name\",\n User.class)\n .setParameter(\"name\", name)\n .getResultList();\n}",
"summary": "Replace verbose JDBC boilerplate with JPA's object-relational mapping and EntityManager.",
"explanation": "JPA (Jakarta Persistence API) maps Java objects to database rows, eliminating manual ResultSet processing and SQL string concatenation. EntityManager provides find(), persist(), and JPQL queries so you work with domain objects instead of raw SQL, while the container manages connection pooling and transactions.",
"whyModernWins": [
{
"icon": "🗺️",
"title": "Object mapping",
"desc": "Entities are plain annotated classes — no manual ResultSet-to-object translation."
},
{
"icon": "🔒",
"title": "Type-safe queries",
"desc": "JPQL operates on entity types and fields rather than raw table and column strings."
},
{
"icon": "⚡",
"title": "Built-in caching",
"desc": "First- and second-level caches reduce database round-trips automatically."
}
],
"support": {
"state": "available",
"description": "Widely available since Jakarta EE 8 / Java 11"
},
"prev": "enterprise/ejb-vs-cdi",
"next": "enterprise/jpa-vs-jakarta-data",
"related": [
"enterprise/servlet-vs-jaxrs",
"enterprise/ejb-vs-cdi",
"io/try-with-resources-effectively-final"
],
"docs": [
{
"title": "Jakarta Persistence Specification",
"href": "https://jakarta.ee/specifications/persistence/"
},
{
"title": "Jakarta Persistence 3.1 API",
"href": "https://jakarta.ee/specifications/persistence/3.1/apidocs/"
}
]
}
54 changes: 54 additions & 0 deletions content/enterprise/jpa-vs-jakarta-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"id": 101,
"slug": "jpa-vs-jakarta-data",
"title": "JPA versus Jakarta Data",
"category": "enterprise",
"difficulty": "intermediate",
"jdkVersion": "21",
"oldLabel": "Jakarta EE 8+",
"modernLabel": "Jakarta EE 11+",
"oldApproach": "JPA EntityManager",
"modernApproach": "Jakarta Data Repository",
"oldCode": "@PersistenceContext\nEntityManager em;\n\npublic User findById(Long id) {\n return em.find(User.class, id);\n}\n\npublic List<User> findByName(String name) {\n return em.createQuery(\n \"SELECT u FROM User u WHERE u.name = :name\",\n User.class)\n .setParameter(\"name\", name)\n .getResultList();\n}\n\npublic void save(User user) {\n em.persist(user);\n}",
"modernCode": "@Repository\npublic interface Users extends CrudRepository<User, Long> {\n List<User> findByName(String name);\n}",
"summary": "Declare a repository interface and let Jakarta Data generate the DAO implementation automatically.",
"explanation": "Jakarta Data (Jakarta EE 11) turns data access into a pure interface declaration. You annotate an interface with @Repository and extend a built-in repository type such as CrudRepository. The runtime generates the implementation — including derived queries from method names like findByName — so there is no EntityManager boilerplate, no JPQL strings, and no hand-written save/find methods.",
"whyModernWins": [
{
"icon": "🪄",
"title": "Zero boilerplate",
"desc": "Declare the interface; the container generates the full DAO implementation at deploy time."
},
{
"icon": "🔍",
"title": "Derived queries",
"desc": "Method names like findByNameAndStatus are parsed automatically — no JPQL or SQL needed."
},
{
"icon": "🔌",
"title": "Portable",
"desc": "Any Jakarta EE 11 compliant runtime provides the repository implementation with no vendor lock-in."
}
],
"support": {
"state": "available",
"description": "Available since Jakarta EE 11 / Java 21 (2024)"
},
"prev": "enterprise/jdbc-vs-jpa",
"next": null,
"related": [
"enterprise/jdbc-vs-jpa",
"enterprise/ejb-vs-cdi",
"enterprise/servlet-vs-jaxrs"
],
"docs": [
{
"title": "Jakarta Data 1.0 Specification",
"href": "https://jakarta.ee/specifications/data/1.0/"
},
{
"title": "Jakarta Data 1.0 API",
"href": "https://jakarta.ee/specifications/data/1.0/apidocs/"
}
]
}
54 changes: 54 additions & 0 deletions content/enterprise/servlet-vs-jaxrs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"id": 98,
"slug": "servlet-vs-jaxrs",
"title": "Servlet versus JAX-RS",
"category": "enterprise",
"difficulty": "intermediate",
"jdkVersion": "11",
"oldLabel": "Java EE",
"modernLabel": "Jakarta EE 8+",
"oldApproach": "HttpServlet",
"modernApproach": "JAX-RS Resource",
"oldCode": "@WebServlet(\"/users\")\npublic class UserServlet extends HttpServlet {\n @Override\n protected void doGet(HttpServletRequest req,\n HttpServletResponse res)\n throws ServletException, IOException {\n String id = req.getParameter(\"id\");\n res.setContentType(\"application/json\");\n res.getWriter().write(\"{\\\"id\\\":\\\"\" + id + \"\\\"}\");\n }\n}",
"modernCode": "@Path(\"/users\")\npublic class UserResource {\n @GET\n @Produces(MediaType.APPLICATION_JSON)\n public Response getUser(\n @QueryParam(\"id\") String id) {\n return Response.ok(new User(id)).build();\n }\n}",
"summary": "Replace verbose HttpServlet boilerplate with declarative JAX-RS resource classes.",
"explanation": "JAX-RS (Jakarta RESTful Web Services) lets you expose REST endpoints using simple annotations like @GET, @Path, and @Produces. No more manual parsing of request parameters or setting content types on the response — the runtime handles marshalling and routing automatically.",
"whyModernWins": [
{
"icon": "📐",
"title": "Declarative routing",
"desc": "Annotations define HTTP method, path, and content type instead of imperative if/else dispatch."
},
{
"icon": "🔄",
"title": "Automatic marshalling",
"desc": "Return POJOs directly; the runtime serialises them to JSON or XML based on @Produces."
},
{
"icon": "🧪",
"title": "Easier testing",
"desc": "Resource classes are plain Java objects, testable without a servlet container."
}
],
"support": {
"state": "available",
"description": "Widely available since Jakarta EE 8 / Java 11"
},
"prev": "language/compact-canonical-constructor",
"next": "enterprise/ejb-vs-cdi",
"related": [
"enterprise/ejb-vs-cdi",
"enterprise/jdbc-vs-jpa",
"io/http-client"
],
"docs": [
{
"title": "Jakarta RESTful Web Services Specification",
"href": "https://jakarta.ee/specifications/restful-ws/"
},
{
"title": "Jakarta REST 3.1 API",
"href": "https://jakarta.ee/specifications/restful-ws/3.1/apidocs/"
}
]
}
2 changes: 1 addition & 1 deletion content/language/compact-canonical-constructor.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"description": "Widely available since JDK 16 (March 2021)"
},
"prev": "language/static-members-in-inner-classes",
"next": null,
"next": "enterprise/servlet-vs-jaxrs",
"related": [
"language/records-for-data-classes",
"language/flexible-constructor-bodies",
Expand Down
3 changes: 2 additions & 1 deletion html-generators/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"datetime": "Date/Time",
"security": "Security",
"tooling": "Tooling",
"enterprise": "Enterprise",
}


Expand Down Expand Up @@ -66,7 +67,7 @@ def load_all_snippets():
snippets = {}
categories = [
"language", "collections", "strings", "streams", "concurrency",
"io", "errors", "datetime", "security", "tooling",
"io", "errors", "datetime", "security", "tooling", "enterprise",
]
json_files = []
for cat in categories:
Expand Down
Loading