💭 Where It All Began
As I write this post, I’m still unemployed. I’ve spent the past six months unemployed. During that time, I stepped out of my comfort zone and transition from frontend to backend. I spent that period learning Java from scratch and building a few small projects using Spring to gain hands-on experience. Once I felt ready, I started sending my CVs again, hoping to land an internship. But soon I realized something tough — getting a job right now isn’t easy. I kept sending my CV everywhere, and most of the time… no one replied. I started asking myself:
“Why am I failing? Why can’t I get a job?”
CV I sent over half of year:

🥀 Facing Reality
It’s hard to accept the truth — I couldn’t find a job.
I had to face the worst-case scenario and come up with a backup plan. My choice? Continue my studies at university after graduating from college. I accepted the truth — that maybe I’m not good enough yet for recruiters to notice. And that’s okay. At that time in university, I had two options:
- Keep sending CVs in the hope for an offer.
- Keep studying, learning, and improving my skills.
With advice from my mentor, I realized that option 1 would only drain my time and motivation. So I chose option 2 — and I’m still learning and growing along the way. You might be thinking:
“Why am I reading a post from some stranger complaining about their life?”
Fair question 😅
But everything I’ve shared so far explains why I started this page, and why I began building my side project — to grow, to learn, and to share my journey along the way. English isn’t my first language, so apologies for any awkward phrasing. I’m doing my best. 🙏
⚙️ Choosing What to Build
With all this free time, I had a choice: waste it doing nothing, or do something meaningful. I wanted to challenge myself and step out of my comfort zone. The question was:
“What kind of system should I build?”
I didn’t want another basic calculator or tic-tac-toe app. I wanted something closer to a real-world system. After researching and comparing ideas, I decided to build a ticket reservation system
🎟️ Why Ticket Booking?
You might ask,
“Why not an e-commerce system?”
I’ve actually built e-commerce projects many times during college, so the topic had become quite repetitive and a bit tiresome. Repeating the same theme again didn’t feel exciting. On top of that, by “e-commerce” here, I mean real-world platforms like Shopee — with complex workflows, multiple teams, and tons of business logic. Simulating a system like that on my own would be extremely challenging, and given my current skill level, I simply didn’t have the capacity to implement it properly.
A ticket booking system, on the other hand, felt balanced — not too simple, not too complicated. The core booking flow is straightforward, but implementing it realistically requires integrating multiple technologies — that’s where the challenge lies.
After analyzing several examples, I found Beta Cinemas as a great reference. And to populate movie data, I used TMDB - an amazing resource for movie metadata. From there, I started designing my first database version (v1). Here’s what it looked like 👇
CREATE TABLE IF NOT EXISTS `user` (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
surname VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS movie (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
poster VARCHAR(255),
overview TEXT,
duration INT NOT NULL,
genre VARCHAR(100),
release_date DATE,
imdb_id VARCHAR(255),
film_id VARCHAR(255)
);
CREATE TABLE IF NOT EXISTS cinema_hall (
id INT PRIMARY KEY AUTO_INCREMENT,
movie_id INT NOT NULL,
movie_session DATETIME NOT NULL,
CONSTRAINT fk_hall_movie FOREIGN KEY (movie_id) REFERENCES movie(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS seat (
id INT PRIMARY KEY AUTO_INCREMENT,
cinema_hall_id INT NOT NULL,
price DECIMAL (10, 2) NOT NULL DEFAULT 0.00,
seat_number VARCHAR(20) NOT NULL,
status ENUM('AVAILABLE', 'BOOKED') DEFAULT 'AVAILABLE',
CONSTRAINT fk_seat_hall FOREIGN KEY (cinema_hall_id) REFERENCES cinema_hall(id) ON DELETE CASCADE,
UNIQUE (cinema_hall_id, seat_number)
);
CREATE TABLE IF NOT EXISTS orders (
id VARCHAR(50) PRIMARY KEY,
user_id BIGINT NOT NULL,
cinema_hall_id INT NOT NULL,
status ENUM('CREATED','CONFIRMED','CANCELLED') DEFAULT 'CREATED',
payment_method ENUM ('MOMO', 'VNPAY', 'ZALOPAY', 'CASH') DEFAULT 'CASH',
payment_status ENUM('PENDING', 'PAID', 'CANCELLED') DEFAULT 'PENDING',
total_amount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
order_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
expired_at DATETIME,
CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE,
CONSTRAINT fk_order_hall FOREIGN KEY (cinema_hall_id) REFERENCES cinema_hall(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS order_seat(
id INT PRIMARY KEY AUTO_INCREMENT,
order_id VARCHAR(50) NOT NULL,
seat_id INT NOT NULL,
price DECIMAL (10, 2) NOT NULL DEFAULT 0.00,
CONSTRAINT fk_order_seat_order FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
CONSTRAINT fk_order_seat FOREIGN KEY (seat_id) REFERENCES seat(id) ON DELETE CASCADE
);
🧩 My Background
As you can see — yeah, it’s not perfect. It’s full of duplication and probably not following normalization rules at all. 😅 But this is a study project, so mistakes are part of the process. Coming from a frontend background, I had almost zero experience with SQL.
Before diving into Java, I mainly worked with the MERN stack (MongoDB, Express, React, Node.js) — my core language was JavaScript, and I built most of my projects with React on the frontend and Node.js/Express on the backend.
Later, I switched to Angular and started learning Java to explore backend development more seriously. So yeah, I didn’t know what DDL, DML, or 1NF/2NF/3NF were. Not even one of them. I’m improving this skill every day — it’s both a strength and a crucial part of backend development.
🔧 Tech Stack and What’s Next
After defining the idea, system flow, and database, I decided on my stack: Angular + Spring Boot + MySQL. And with that, I finally started building my full-stack system. What happens next? You’ll have to wait for the next post. 😉 Thanks for reading all the way here — I really appreciate it. This post isn’t just about code — it’s about growth, failure, and persistence.
See you in the next one. 👋