Layered architecture in enterprise Java means splitting an application into controller, service, repository and entity layers, each with one job. The controller handles web requests, the service holds business rules, the repository talks to the database, and the entity models the data. Once you can say which layer a piece of logic belongs to, most Java backend code becomes far easier to read, test and change.
Why Java backends are split into layers
A small program can put everything in one class: read input, check rules, run SQL, print output. It works until the first change. If the discount rule changes, you edit the same file that parses HTTP requests and writes SQL. A bug in one concern breaks the others, and testing requires a running database and a web server.
Layering fixes this by separating concerns. Each layer depends only on the layer directly below it:
- Controller depends on the service.
- Service depends on the repository.
- Repository depends on the entity and the database.
- Entity depends on nothing above it.
The practical benefits are that you can swap a database without rewriting business rules, test rules without starting a server, and let several developers work on different layers at once. Frameworks such as Spring Boot encourage this structure with annotations like @RestController, @Service, @Repository and @Entity, but the idea is independent of any framework.
Annotated diagram of an order system
The running example is a deliberately small order system: a customer places an order for products, stock must be available, and the total is calculated. The diagram below is illustrative, not output from a real project.
HTTP client (browser / mobile app / Postman)
| POST /orders (JSON)
v
+-----------------------------+
| CONTROLLER OrderController | parse request, validate shape,
| | call service, return HTTP status
+-----------------------------+
| OrderRequest (DTO)
v
+-----------------------------+
| SERVICE OrderService | business rules: stock check,
| | total, discount, transaction
+-----------------------------+
| entities
v
+-----------------------------+
| REPOSITORY OrderRepository | save, find, query;
| ProductRepository| no business decisions
+-----------------------------+
| SQL / JPA
v
+-----------------------------+
| ENTITY Order, OrderItem| fields, relationships,
| Product | simple self-contained behaviour
+-----------------------------+
|
Database
Reading the diagram line by line
- The arrows point downward. A controller may call a service; a repository must never call a controller.
- The DTO between controller and service. A Data Transfer Object such as
OrderRequestcarries only what the client sends. It keeps the web format separate from the database model. - Entities sit at the bottom. They are the shared vocabulary that the repository stores and the service manipulates.
- The database is outside the layers. Only the repository should know it exists.
Free 2-Week CareerSwami Internship
Online, 14 days, with a free offer letter and a free completion certificate once you finish the work. Check with your college that it fits your requirement before you enrol.
What each layer owns in the order system
| Layer | Responsibility | Order system examples | Should not contain |
|---|---|---|---|
| Controller | Translate HTTP to Java and back | Map POST /orders, check required fields exist, return 201 or 400 |
Stock rules, price calculation, SQL |
| Service | Business rules and transactions | Check stock, compute total, apply discount, decide if an order can be cancelled | HTTP classes, SQL strings |
| Repository | Persistence access | findByCustomerId, save, a query for orders in a date range |
Discount rules, status decisions |
| Entity | Data structure and its own invariants | Order has items and a status; an item’s line total is quantity times unit price | Database calls, HTTP details |
Illustrative code skeleton for each layer
The following skeleton is illustrative and simplified. It has not been compiled or run, and a real project would need imports, configuration and error handling.
// ENTITY
@Entity
public class Product {
@Id @GeneratedValue private Long id;
private String name;
private BigDecimal price;
private int stock;
// getters and setters
}
// REPOSITORY
public interface ProductRepository extends JpaRepository<Product, Long> { }
// SERVICE
@Service
public class OrderService {
private final ProductRepository products;
private final OrderRepository orders;
public OrderService(ProductRepository products, OrderRepository orders) {
this.products = products;
this.orders = orders;
}
@Transactional
public Order placeOrder(OrderRequest request) {
// look up products, reject if stock is too low,
// reduce stock, compute total, save the order
}
}
// CONTROLLER
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderService service;
public OrderController(OrderService service) { this.service = service; }
@PostMapping
public ResponseEntity<Order> create(@RequestBody OrderRequest request) {
return ResponseEntity.status(201).body(service.placeOrder(request));
}
}
Notice that the controller is almost empty. That is a good sign: it only receives, delegates and responds. The weight of the application sits in the service.
Tracing one request through the four layers
Take a customer ordering 2 units of a product priced at 500 with 5 units in stock (illustrative numbers).
- Controller: receives the JSON, converts it into an
OrderRequest, and callsplaceOrder. - Service: asks the repository for the product, sees stock 5 is at least 2, reduces stock to 3, calculates a total of 1000, and builds the order.
- Repository: saves the updated product and the new order inside the same transaction.
- Entity: the saved
Ordercarries its items and status, for examplePLACED. - Back up the chain: the service returns the order, and the controller replies with status 201.
Now change the requirement: orders above 5000 get a 10 percent discount. Only the service changes. The controller, repository and entity stay untouched. That is the payoff of layering.
Quiz: which layer does this logic belong in?
For each item, decide on the layer before reading the answer key below.
- Reject an order if the requested quantity exceeds available stock.
- Return HTTP 404 when an order id does not exist.
- Write a query that finds all orders placed by one customer.
- Calculate the total of an order including a festival discount.
- Declare that an order has many order items.
- Check that the JSON body contains a non-empty customer id.
- Decide that a shipped order can no longer be cancelled.
- Mark a method as running inside one database transaction.
- Convert an
OrderRequestinto anOrderobject. - Send a confirmation email after an order is placed.
Answer key with reasoning
| # | Layer | Why |
|---|---|---|
| 1 | Service | A business rule about stock |
| 2 | Controller | HTTP status is a web concern; the service may signal “not found” with an exception that the controller layer translates |
| 3 | Repository | A data access query |
| 4 | Service | Pricing and discount policy are business rules |
| 5 | Entity | A relationship in the data model |
| 6 | Controller | Shape validation of the incoming request |
| 7 | Service | A rule about allowed status changes (an entity method may hold the check, called by the service) |
| 8 | Service | Transaction boundaries belong where a business operation is defined |
| 9 | Service | Mapping can sit in the service or a dedicated mapper called by it; it should not leak into the repository |
| 10 | Service | A side effect of the business operation; in larger systems it moves to an event or a separate notification component the service calls |
Items 2, 7, 9 and 10 have defensible variations. In interviews, explain your reasoning rather than just naming a layer.
A worked refactoring: untangling a fat controller
This illustrative snippet shows a typical beginner mistake.
@PostMapping("/orders")
public String create(@RequestBody OrderRequest r) {
Product p = jdbc.queryForObject("SELECT * FROM product WHERE id=?", ...);
if (p.getStock() < r.getQty()) return "Out of stock";
double total = p.getPrice() * r.getQty();
if (total > 5000) total = total * 0.9;
jdbc.update("INSERT INTO orders ...");
return "OK";
}
It mixes four concerns. Splitting it gives this plan:
- Move the SQL into
ProductRepositoryandOrderRepository. - Move the stock check and discount into
OrderService.placeOrder. - Use
BigDecimalfor money instead ofdouble. - Return a proper status code and body from the controller instead of a plain string.
Layering decisions checklist for your own project
| Check | Pass condition |
|---|---|
| Controller size | Each method is a few lines: receive, delegate, respond |
| Imports in the service | No javax/jakarta.servlet or HTTP classes |
| Imports in the controller | No repository or SQL classes |
| Entities exposed to clients | Prefer DTOs so internal fields are not leaked |
| Unit tests | Service rules can be tested with a mocked repository |
| Transactions | Defined on service methods that change several records |
| Dependency direction | Only downward, never a repository calling a service |
Layering mistakes that beginners make
- Anemic everything: a service that only forwards calls to the repository. If no rule exists yet, that is fine, but do not invent layers just to look enterprise-grade.
- Returning entities straight from the controller: lazy-loaded relationships and internal fields can leak or cause errors. Use DTOs.
- Business logic in repository queries: a query that quietly hides a discount rule makes the rule hard to find.
- Using
doublefor money: rounding errors appear; useBigDecimal. - Circular dependencies: two services calling each other usually signals a missing third component.
SDM University students: applying layered architecture to your own learning path
The university was established under the Shri Dharmasthala Manjunatheshwara University Act 2018 as a State Private University at Sattur, Dharwad. Its homepage lists constituent institutions focused on medical sciences, dental sciences, nursing, physiotherapy, pharmaceutical sciences and biomedical research. Its Curriculum page links programme PDFs that are mainly health-sciences programmes, with an MBA in Hospital Administration and an M.Sc Computational Biology among the other items.
In practice this means a Java enterprise course may not be part of your regular timetable, so layered architecture is likely something you will learn on your own or through an elective, a project or a data-related course. That is not a drawback for this topic. Health-sector software is full of order-like workflows: appointment bookings, pharmacy stock, lab requests and billing. An order system with controller, service, repository and entity layers maps directly onto, for example, a pharmacy stock and dispensing module. Treat that as an idea for a personal project, not a claim about any university curriculum.
The university’s Placement Cell page is generic: it describes recruitment drives and resume and interview preparation, and does not publish statistics or a recruiter list. So do not assume a particular Java hiring route exists; build a visible project instead. A small layered application on GitHub, with a short README explaining each layer, is concrete evidence you can show.
If you want structured practice, CareerSwami offers a free two-week online internship with a free offer letter and a free completion certificate after successful completion, across 26 tracks. It is an independent guide and is not connected to the university.
Steps to verify how this fits your programme
- Open your programme’s PDF on the Curriculum page and look for any computing, programming or data course, and note its exact title.
- Ask your department coordinator in writing whether online internships or self-directed projects are recognised, and whether rules are set by the university or your constituent college.
- Check the Examinations page and the University Prospectus 2026-27 for any internship or project-work regulation.
- Email the Placement Cell at placementcell@sdmuniversity.edu.in and ask whether any software or health-IT roles are offered through campus drives.
- Before submitting any certificate to the university, ask which document format and signatory it requires.
A 14-day plan to practise the four layers
| Days | Focus | Output |
|---|---|---|
| 1-2 | Java basics refresh, Maven or Gradle, project setup | Running skeleton project |
| 3-4 | Entities: Product, Order, OrderItem and relationships | Entity classes and table mapping |
| 5-6 | Repositories and basic queries | Save and fetch working against a test database |
| 7-9 | Service layer: stock check, total, discount, transaction | Business rules in one place |
| 10-11 | Controller, DTOs, status codes, validation | Working REST endpoints |
| 12-13 | Unit tests for the service with a mocked repository | Passing tests for core rules |
| 14 | README with annotated layer diagram | Portfolio-ready repository |
Frequently Asked Questions
Is layered architecture the same as MVC?
They overlap but are not identical. MVC splits presentation into model, view and controller. In a Spring REST backend, the controller layer plays the web-facing part, while the service and repository layers organise the business and data side behind it.
Do I always need a service layer?
For tiny CRUD apps, a thin service is optional. As soon as there is a business rule, a transaction across several records, or logic reused by several controllers, a service layer pays off.
Where should validation go?
Shape validation, such as required fields and formats, usually goes at the controller boundary. Business validation, such as stock availability, goes in the service. Database constraints still act as a last line of defence.
Should entities contain logic?
Small rules that concern only the entity itself, such as computing a line total from its own fields, can live there. Rules that need other entities or a repository belong in the service.
Why use DTOs instead of returning entities?
DTOs keep your API stable when the database model changes, avoid exposing internal fields, and sidestep lazy-loading problems during JSON serialisation.
Can I learn this without a computer science programme?
Yes. The concepts need Java fundamentals and patience, not a particular degree. Build the order system step by step, and check with your department whether such learning can be reflected in your programme records.
Does layered architecture apply outside Spring?
Yes. Jakarta EE, Micronaut, Quarkus and plain Java all benefit from the same separation. Only the annotations and configuration change.
What should I learn after the four layers?
Move on to exception handling across layers, integration tests with a test database, security basics, and then patterns such as hexagonal architecture, which push the same separation further.
Related Java & Enterprise Software guides
- PES University Students: Reviewing a Java Pull Request Like an Intern Who Wants to Learn
- Apex University Students: A Final-Week Checklist for Wrapping Up a Java Internship
- Vikrant University Students: Time Planning for a Java Internship During Exam Season
- All Java & Enterprise Software internship guides
Ready to put this into practice?
Join the free two-week CareerSwami online internship in Java & Enterprise Software. The internship, the offer letter and the completion certificate are free.




