Inside `hotel-management-system-servlet-hibernate-jsp`: A Hotel App That Shows Its Jakarta EE Guts

A multi-role booking system that uses Servlets, JSP, Hibernate, and MySQL not as abstractions, but as visible machinery, from BLOB-stored images to session checks and hybrid querying.

7 min read • View on GitHub • More from Mohammed-Masood-Ansari

A hotel reception desk drawn as a transparent machine, with the check-in counter in front and the stack visible underneath. A request path runs through a servlet valve, a session gate, and a database cylinder that holds hotel images like physical cargo. It explains that the real story here is not the hotel UI, but the exposed plumbing behind it.
The repo reads like a cross-section of a classic Java web app. The hotel workflow is simple, but the machinery underneath is the point.
Key Takeaways

What This Repo Really Is

This is a multi-role hotel management system for admins, hotel owners, and customers. That matters less than how openly it exposes the stack: DTOs for data, DAOs for persistence, servlets for routing, and JSP for rendering. It feels less like a polished SaaS product and more like a readable specimen of old-school Java web development.

That is the value. The project shows what a Java EE app looks like when you can see the seams, from session checks to multipart uploads to Hibernate mappings. For a technically curious reader, the transparency is the feature.

The architecture is not hidden. A user request moves through controller, DAO, entity, and database layers in a way that is easy to trace and easy to teach.

The Stack Is the Point

The repo follows a classic Model 2 MVC layout. DTOs act as the model, DAOs own persistence, servlets route requests, and JSP files render the interface. That structure is simple on paper, but in practice it teaches how a Java web app actually moves work across layers.

A booking request does not disappear into a framework. It lands in a controller, gets checked against session state, passes through a DAO, becomes an entity operation, and comes back as a JSP response. That visibility is the educational payoff.

if (httpSession.getAttribute("adminSession") != null) {
    // admin-only flow
} else {
    response.sendRedirect("admin-login.jsp");
}

The Weirdest Choice Is Also the Most Teachable

The standout decision is storing hotel images directly in MySQL as `LONGBLOB`. That is not the default choice in modern systems, where images usually live in object storage or on disk while the database keeps a path. Here, the image itself becomes part of the row-level data model.

A close-up of a hotel photograph being lowered into a database vault like a physical object. One path suggests compact, self-contained backup, while the other path bends into a crowded table of heavy records and slower reads. It explains the trade-off between storing binaries in the database and keeping them on the file system.
BLOB storage is memorable because it is so concrete. It simplifies backup and deployment, but it also makes the database heavier and less flexible.
ApproachWhat it buys youWhat it costs you
Store image as `LONGBLOB`One database contains the full recordBigger tables and slower reads
Store file path in DBSmaller rows and easier cachingTwo systems to keep in sync
Store in object storageScales well for mediaMore infrastructure and wiring

That trade-off is the whole point. For a small teaching project, it is a defensible simplification. For production, it is exactly the kind of decision that makes ops teams nervous.

Security Without a Safety Net

The authorization model is hand-rolled. Controllers inspect session attributes to decide whether a request belongs to an admin, owner, or customer. That is straightforward, and it shows the reader what security looks like before a framework starts managing it for you.

if (httpSession.getAttribute("ownerSession") != null) {
    // owner-only action
} else {
    response.sendRedirect("owner-login.jsp");
}

This approach is easy to follow, but it also spreads access-control logic across controllers. That is the trade-off: clarity for a beginner, repetition for a maintainer.

Hybrid Persistence, Old and New in the Same Repo

The persistence layer mixes `find()`, JPQL, native SQL, and even Java-side stream filtering. That makes the developer look comfortable across the Hibernate toolbox, but it also reveals a loose consistency model.

TechniqueWhere it appearsWhy it matters
`find()`Primary-key lookupsDirect and idiomatic for single records
JPQLEntity queriesKeeps logic object-oriented
Native SQLStatus updatesFast to write, less portable
Java streamsVerified hotel filteringReadable, but shifts work out of the database

The most interesting case is in-memory filtering of verified hotels. It is fine at small scale. It is also a reminder that code convenience can quietly become database inefficiency.

What the Controllers Reveal About the App

`HotelRegisterController` shows the app’s most manual mechanics. It handles multipart form data, reads uploaded image bytes into a `byte[]`, and hands that data to the persistence layer. Nothing is hidden.

`HotelBookController` is equally direct. It creates a booking identifier with a custom string pattern and moves the booking through the system as a straightforward transaction. The design is plain, but it is easy to reason about because the controller owns the full flow.

byte[] hotelImage = inputStream.readAllBytes();
String bookingId = "jsp" + Math.abs(Math.random() * 1000000);

How It Compares

A modern Spring Boot hotel app would hide more of this plumbing behind annotations, auto-configuration, and convention. A more typical JSP servlet project might look similar on the surface but be less explicit about the odd choices that make this repo interesting.

Project typeWhat you learnWhat you lose
This repoHow classic Jakarta EE layers talk to each otherProduction polish and abstraction
Modern Spring Boot appFast delivery and framework conventionsVisibility into the lower-level mechanics
Typical educational JSP appBasic CRUD patternsThe unusual implementation details that make architecture memorable

That is why the project stands out. It is not trying to be the best hotel system. It is trying, whether intentionally or not, to show exactly how the machinery works.

Why This Repo Matters

The repo’s value is pedagogical. It turns a basic hotel workflow into a readable blueprint for classic Java web development, and it does so with just enough oddity to keep the reader awake. The BLOB choice, the session checks, and the mixed persistence strategies all expose design decisions that modern stacks usually smooth over.

If you want a clean example of Jakarta EE without much abstraction, this is it. It is not production-hardened, but it is legible, and that makes it useful.