A console-based Expense Tracker application built using Core Java and Hibernate ORM. This project demonstrates clean backend design, manual transaction handling, and proper ORM usage without relying on Spring Boot.
App (CLI) | Service Layer | Repository (DAO) Layer | Hibernate ORM | MySQL Database
- User registration with unique username
- Secure login using username & password
- Account recovery for deactivated users
- Change password functionality
- Account deactivation (soft delete)
- Permanent account deletion
- User account status management (active, deleted)
- View general categories
- Create user-specific categories
- Fetch category details by category ID
- Delete user-owned categories only
-
Enforced uniqueness:
- One user cannot have two categories with the same name
- Automatic cleanup of categories when user is deleted (CASCADE)
- Add a single expense
- Add multiple expenses in one session
- View all expenses for a user
- Fetch expense by expense ID
- View expenses by month and year
- Update expense amount and category
- Soft delete expenses (status-based)
- Restore soft-deleted expenses
- Permanent deletion of expenses
- User-wise data isolation (users can only access their own data)
- Foreign key enforcement using database constraints
- CASCADE deletes ensure no orphan records
- Soft delete preserves data history where required
- Input validation for numeric fields (prevents crashes)
- Unique username enforced at database level
- Unique (User_Id, Category_Name) enforced at database level
-
Referential integrity maintained between:
- User → Category
- User → Expense
- Category → Expense
- Built using Java 8
- Hibernate ORM for database operations
-
Clean separation of layers:
- Entity layer
- Repository layer
- Service layer
- Maven-based project (pom.xml)
- CLI-based interface (terminal application)
- Ready for migration to Spring Boot + REST APIs
The Expense Tracker application uses a relational database with three core tables:
- user
- category
- expense
The schema is designed to:
- Maintain user-wise data ownership
- Enforce referential integrity using foreign keys
- Support soft deletion using status columns
- Enforce data uniqueness at the database level
- Automatically clean up dependent records using CASCADE rules
Stores user account details. Each user owns categories and expenses.
| Column Name | Data Type | Description |
|---|---|---|
User_Id |
int (PK, AI) | Unique identifier for each user |
User_name |
varchar(45) | Username |
User_Password |
varchar(108) | User password |
Age |
int | User age |
Status |
enum('active','deleted') | Account status |
- UNIQUE (User_name)
- Each username is globally unique
Status = 'deleted'represents a deactivated account- A user can have multiple categories and expenses
Stores expense categories. Categories are user-specific.
| Column Name | Data Type | Description |
|---|---|---|
Category_id |
int (PK, AI) | Unique category identifier |
Category_Name |
varchar(45) | Name of the category |
User_id |
int (FK) | Owner user |
- UNIQUE (
User_id,Category_Name)
| Foreign Key | References | On Update | On Delete |
|---|---|---|---|
User_id |
user(User_Id) |
CASCADE | CASCADE |
- A user cannot create two categories with the same name
- Different users can have categories with the same name
- If a user is deleted, all related categories are automatically deleted
Stores individual expense records created by users.
| Column Name | Data Type | Description |
|---|---|---|
Expense_Id |
int (PK, AI) | Unique expense identifier |
Category_Id |
int (FK) | Category of the expense |
User_Id |
int (FK) | Owner user |
Amount |
decimal(10,2) | Expense amount |
Date |
timestamp | Date and time of expense |
Status |
enum('ACTIVE','DELETED') | Expense state |
| Foreign Key | References | On Update | On Delete |
|---|---|---|---|
User_Id |
user(User_Id) |
CASCADE | CASCADE |
Category_Id |
category(Category_id) |
CASCADE | CASCADE |
- Expenses support soft delete using
Status - Deleting a user or category automatically deletes related expenses
- Expense uniqueness is not restricted; multiple expenses can exist in the same category
- One User → Many Categories
- One User → Many Expenses
- One Category → Many Expenses
All relationships are enforced using foreign keys with CASCADE, ensuring no orphan records exist.
- Username uniqueness prevents account ambiguity
- (User_Id + Category_Name) uniqueness enforces clean category organization per user
- CASCADE deletes simplify database cleanup
- Soft delete preserves logical history without immediate data loss
- Schema maps cleanly to Hibernate / JPA entities
- Ready for migration to Spring Boot + Spring Data JPA
ALTER TABLE user
ADD CONSTRAINT UNIQUE (User_name);
ALTER TABLE category