-
Notifications
You must be signed in to change notification settings - Fork 4
employee-dev-13-BE-add-ticket-table-back #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
# 🎫 Ticket System - Database Auto-Creation Setup | ||
|
||
This document explains the backend configuration for automatic ticket table creation in the Employee Management System. | ||
|
||
## 🚀 **What's Been Fixed** | ||
|
||
### ✅ **Enhanced Ticket Entity (`Ticket.java`)** | ||
- **Fixed LONGTEXT Column**: Changed from `TEXT` to `LONGTEXT` for better MySQL compatibility | ||
- **Added Timestamps**: Automatic `createdAt` and `updatedAt` tracking | ||
- **Removed Manual SQL**: No more manual `ALTER TABLE` commands needed | ||
- **Better Annotations**: Proper JPA annotations for robust table creation | ||
|
||
### ✅ **Improved Application Configuration (`application.properties`)** | ||
- **MySQL 8 Dialect**: Updated to use MySQL 8 dialect for better compatibility | ||
- **Enhanced Logging**: Added detailed SQL logging for debugging | ||
- **Auto DDL Update**: Proper Hibernate DDL configuration | ||
- **Formatted SQL**: Better readable SQL output in logs | ||
|
||
### ✅ **Database Configuration Class (`DatabaseConfig.java`)** | ||
- **Guaranteed Table Creation**: Programmatic table creation with proper indexes | ||
- **Error Handling**: Comprehensive error handling and logging | ||
- **Table Verification**: Automatic table structure verification on startup | ||
- **Performance Indexes**: Added indexes for better query performance | ||
|
||
### ✅ **Sample Data Initialization (`data.sql`)** | ||
- **Schema Data**: Pre-populated ticket statuses and tags | ||
- **Sample Tickets**: Example tickets for testing | ||
- **Safe Inserts**: Uses `INSERT IGNORE` to prevent duplicates | ||
|
||
## 🛠️ **New Features Added** | ||
|
||
### 📅 **Automatic Timestamps** | ||
```java | ||
@CreationTimestamp | ||
private LocalDateTime createdAt; | ||
|
||
@UpdateTimestamp | ||
private LocalDateTime updatedAt; | ||
``` | ||
|
||
### 🗃️ **Performance Indexes** | ||
- `idx_user_id` - Fast queries by user | ||
- `idx_assigned_to` - Fast queries by assignee | ||
- `idx_status` - Fast status filtering | ||
- `idx_created_at` - Time-based queries | ||
|
||
### 🔧 **Enhanced Service Layer** | ||
- **Proper Updates**: No more delete+insert operations | ||
- **Timestamp Preservation**: Maintains creation time during updates | ||
- **Error Handling**: Better exception handling | ||
|
||
## 🚀 **How It Works** | ||
|
||
### 1. **Application Startup** | ||
``` | ||
Spring Boot starts | ||
↓ | ||
DatabaseConfig.initDatabase() runs | ||
↓ | ||
CREATE TABLE IF NOT EXISTS tickets | ||
↓ | ||
Table structure verification | ||
↓ | ||
data.sql executes (if present) | ||
↓ | ||
Sample data inserted | ||
``` | ||
|
||
### 2. **Ticket Operations** | ||
``` | ||
Create Ticket → createdAt auto-set | ||
Update Ticket → updatedAt auto-updated | ||
Query Tickets → Fast with indexes | ||
``` | ||
|
||
## 📋 **Table Structure** | ||
|
||
| Column | Type | Description | | ||
|--------|------|-------------| | ||
| `id` | INT AUTO_INCREMENT | Primary key | | ||
| `subject` | VARCHAR(255) | Ticket title | | ||
| `description` | LONGTEXT | Detailed description | | ||
| `user_id` | INT | Creator user ID | | ||
| `assigned_to` | INT | Assignee user ID | | ||
| `status` | VARCHAR(50) | Current status | | ||
| `tag` | VARCHAR(100) | Ticket category | | ||
| `created_at` | TIMESTAMP | Auto creation time | | ||
| `updated_at` | TIMESTAMP | Auto update time | | ||
|
||
## 🔍 **Verification** | ||
|
||
### **Check Table Creation** | ||
```sql | ||
DESCRIBE tickets; | ||
SHOW CREATE TABLE tickets; | ||
``` | ||
|
||
### **View Sample Data** | ||
```sql | ||
SELECT * FROM tickets; | ||
SELECT * FROM option_schema WHERE schema_name LIKE 'ticket%'; | ||
``` | ||
|
||
### **Check Indexes** | ||
```sql | ||
SHOW INDEX FROM tickets; | ||
``` | ||
|
||
## 🧪 **Testing** | ||
|
||
Run the included test: | ||
```bash | ||
mvn test -Dtest=DatabaseConfigTest | ||
``` | ||
|
||
## 🐛 **Troubleshooting** | ||
|
||
### **Table Not Created** | ||
1. Check MySQL connection | ||
2. Verify database exists | ||
3. Check application logs for errors | ||
4. Ensure proper MySQL permissions | ||
|
||
### **Column Type Issues** | ||
- The entity now uses `LONGTEXT` instead of `TEXT` | ||
- Should work with both MySQL 5.7+ and MySQL 8+ | ||
- No manual table alterations needed | ||
|
||
### **Timestamp Issues** | ||
- Timestamps are handled automatically by Hibernate | ||
- `@CreationTimestamp` and `@UpdateTimestamp` annotations | ||
- No manual date setting required | ||
|
||
## 📝 **Sample Usage** | ||
|
||
### **Create Ticket** | ||
```java | ||
Ticket ticket = new Ticket(); | ||
ticket.setSubject("Bug Report"); | ||
ticket.setDescription("Found a critical bug"); | ||
ticket.setUserId(1); | ||
ticket.setStatus("PENDING"); | ||
ticketRepository.save(ticket); // Timestamps set automatically | ||
``` | ||
|
||
### **Update Ticket** | ||
```java | ||
TicketDto dto = new TicketDto(); | ||
dto.setId(1); | ||
dto.setStatus("APPROVED"); | ||
ticketService.updateTicket(dto); // updatedAt set automatically | ||
``` | ||
|
||
## ✅ **Success Indicators** | ||
|
||
When everything works correctly, you should see: | ||
``` | ||
✅ Tickets table created or verified successfully | ||
📋 Tickets table structure: | ||
id - int - NO | ||
subject - varchar(255) - NO | ||
description - longtext - YES | ||
user_id - int - YES | ||
assigned_to - int - YES | ||
status - varchar(50) - YES | ||
tag - varchar(100) - YES | ||
created_at - timestamp - NO | ||
updated_at - timestamp - NO | ||
``` | ||
|
||
The ticket system is now fully configured for automatic table creation and management! 🎉 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package EmployeeSystem.config; | ||
|
||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.boot.CommandLineRunner; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import javax.sql.DataSource; | ||
import java.sql.Connection; | ||
import java.sql.Statement; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@Configuration | ||
public class DatabaseConfig { | ||
|
||
@Autowired | ||
private DataSource dataSource; | ||
|
||
@Bean | ||
public CommandLineRunner initDatabase() { | ||
return args -> { | ||
try (Connection connection = dataSource.getConnection()) { | ||
// Ensure the tickets table exists with proper structure | ||
String createTicketsTable = "CREATE TABLE IF NOT EXISTS tickets (" + | ||
"id INT AUTO_INCREMENT PRIMARY KEY," + | ||
"subject VARCHAR(255) NOT NULL," + | ||
"description LONGTEXT," + | ||
"user_id INT," + | ||
"assigned_to INT," + | ||
"status VARCHAR(50) DEFAULT 'PENDING'," + | ||
"tag VARCHAR(100)," + | ||
"created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP," + | ||
"updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP," + | ||
"INDEX idx_user_id (user_id)," + | ||
"INDEX idx_assigned_to (assigned_to)," + | ||
"INDEX idx_status (status)," + | ||
"INDEX idx_created_at (created_at)" + | ||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"; | ||
Comment on lines
+25
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a |
||
|
||
try (Statement statement = connection.createStatement()) { | ||
statement.execute(createTicketsTable); | ||
log.info("✅ Tickets table created or verified successfully"); | ||
|
||
// Verify table structure | ||
java.sql.ResultSet resultSet = statement.executeQuery("DESCRIBE tickets"); | ||
log.info("📋 Tickets table structure:"); | ||
while (resultSet.next()) { | ||
log.info(" {} - {} - {}", | ||
resultSet.getString("Field"), | ||
resultSet.getString("Type"), | ||
resultSet.getString("Null")); | ||
} | ||
} | ||
|
||
} catch (Exception e) { | ||
log.error("❌ Failed to initialize tickets table: {}", e.getMessage()); | ||
throw new RuntimeException("Database initialization failed", e); | ||
} | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ | |
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
import lombok.ToString; | ||
import org.hibernate.annotations.CreationTimestamp; | ||
import org.hibernate.annotations.UpdateTimestamp; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
|
||
|
||
@Entity | ||
|
@@ -27,19 +30,11 @@ public class Ticket { | |
* Updated the @Column annotation for description to use columnDefinition = "TEXT". | ||
* This tells Hibernate to create the column as a TEXT type in the database, | ||
* which can hold much larger strings compared to a VARCHAR. | ||
* | ||
* | ||
* NOTE !!! | ||
* if app failed to start, comment out "@Column(name = "description", columnDefinition = "TEXT")" | ||
* start app, then modify table attr type manually via below cmd : | ||
* | ||
* ALTER TABLE tickets MODIFY COLUMN description TEXT; | ||
* | ||
* -> then run app again | ||
* | ||
* Fixed to work with both MySQL 5 and MySQL 8 for auto table creation. | ||
*/ | ||
Comment on lines
+34
to
35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
//@Column(name = "description") | ||
@Column(name = "description", columnDefinition = "TEXT") | ||
private String description; // Use TEXT type for longer strings | ||
@Column(name = "description", columnDefinition = "LONGTEXT") | ||
private String description; // Use LONGTEXT type for longer strings | ||
|
||
@Column(name = "user_id") | ||
private Integer userId; | ||
|
@@ -52,4 +47,12 @@ public class Ticket { | |
|
||
@Column(name = "tag") | ||
private String tag; | ||
|
||
@CreationTimestamp | ||
@Column(name = "created_at", nullable = false, updatable = false) | ||
private LocalDateTime createdAt; | ||
|
||
@UpdateTimestamp | ||
@Column(name = "updated_at", nullable = false) | ||
private LocalDateTime updatedAt; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
-- This file will be executed by Spring Boot on startup to initialize data | ||
-- It creates sample data for testing the ticket system | ||
|
||
-- Insert sample ticket statuses into option_schema if they don't exist | ||
INSERT IGNORE INTO option_schema (column_name, schema_name, active) VALUES | ||
('PENDING', 'ticket_status', true), | ||
('CREATED', 'ticket_status', true), | ||
('REVIEWING', 'ticket_status', true), | ||
('APPROVED', 'ticket_status', true), | ||
('REJECTED', 'ticket_status', true), | ||
('CANCELLED', 'ticket_status', true); | ||
|
||
-- Insert sample ticket tags into option_schema if they don't exist | ||
INSERT IGNORE INTO option_schema (column_name, schema_name, active) VALUES | ||
('Bug Report', 'ticket_tag', true), | ||
('Feature Request', 'ticket_tag', true), | ||
('Technical Support', 'ticket_tag', true), | ||
('HR Request', 'ticket_tag', true), | ||
('IT Support', 'ticket_tag', true), | ||
('General Inquiry', 'ticket_tag', true); | ||
|
||
-- Create sample tickets if tickets table is empty | ||
INSERT IGNORE INTO tickets (id, subject, description, user_id, assigned_to, status, tag, created_at, updated_at) VALUES | ||
(1, 'Sample IT Support Ticket', 'This is a sample ticket for IT support request to test the system functionality.', 1, 2, 'PENDING', 'IT Support', NOW(), NOW()), | ||
(2, 'Feature Request Example', 'Sample feature request ticket to demonstrate the ticketing system capabilities.', 2, 1, 'REVIEWING', 'Feature Request', NOW(), NOW()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SQL schema defines
user_id
andassigned_to
asINT
columns. It would be beneficial to add foreign key constraints referencing theusers
table (assuming one exists) to enforce referential integrity at the database level. This helps prevent orphaned tickets if users are deleted.