A production-ready Discord bot framework built with JDA v5 and Hibernate ORM — supports SQLite, PostgreSQL, and MySQL with a modular src/ architecture.
Features • Quick Start • Structure • Database Config • API • MongoDB Edition • Ecosystem
Discord Handler Java (SQL Edition) is the Java Sequelize variant of the multi-language Discord Handler ecosystem. Built on JDA v5 with Hibernate ORM, it provides an event-driven foundation for Discord bots with dual command support (slash + prefix), relational database persistence, webhook-based logging, and a comprehensive anti-crash layer.
The entry point (Main.java) boots in a predictable sequence: initialize the anti-crash handler, configure the Hibernate SessionFactory, load slash commands, prefix commands, events, and JPA entities, present a startup report, and finally log in. A graceful shutdown hook for SIGINT/SIGTERM is also registered.
- Dual Command System — Slash commands via JDA's
SlashCommandInteractionEventand prefix commands viaMessageReceivedEvent - Modular Architecture — Separated concerns across
core/,database/,events/,handlers/,models/, andcommands/ - Java 21 — Built on modern Java with records and sealed classes
- Anti-Crash — Global
Thread.setDefaultUncaughtExceptionHandlerinterception viaAntiCrash.java - Webhook Logging — Six dedicated webhooks: errors, slash commands, prefix commands, guild join, guild leave, and ready
- Hibernate ORM — Persistent storage via Hibernate 6.3 with JPA annotations, supporting SQLite, PostgreSQL, and MySQL
- Cooldown System — Per-command cooldown tracked in
core/CommandUtils.java - Environment Configuration — All secrets managed via
dotenv-javainConfig.java - Maven Build — Dependency management and packaging via Maven with shade plugin
git clone https://github.com/RealMtrx/Discord-Handler-Java-Sequelize.git
cd Discord-Handler-Java-Sequelize
mvn clean compileCopy .env.example to .env and fill in your values:
TOKEN=your_bot_token
CLIENT_ID=your_client_id
BOT_NAME=Discord Handler
OWNER_IDS=owner_id_1,owner_id_2
PREFIX=$
DB_DIALECT=SQLITE
DB_URL=jdbc:sqlite:discord_bot.db
ERROR_WEBHOOK=your_webhook_url
SLASH_WEBHOOK=your_webhook_url
PREFIX_WEBHOOK=your_webhook_url
JOIN_WEBHOOK=your_webhook_url
LEAVE_WEBHOOK=your_webhook_url
READY_WEBHOOK=your_webhook_urlmvn exec:java -Dexec.mainClass="Main"
# or package and run
mvn clean package
java -jar target/discord-handler-sequelize-1.0.0.jar| Package | Version | Purpose |
|---|---|---|
JDA |
5.2.0 | Discord API wrapper |
hibernate-core |
6.3.1.Final | Hibernate ORM |
hibernate-community-dialects |
6.3.1.Final | SQLite dialect support |
sqlite-jdbc |
3.45.1.0 | SQLite database driver |
dotenv-java |
3.1.0 | Environment variable management |
gson |
2.11.0 | JSON parsing for webhooks |
Discord-Handler-Java-Sequelize/
├── pom.xml # Maven project configuration
├── src/
│ ├── Main.java # Entry point — async boot sequence
│ ├── Config.java # Bot configuration (token, prefixes, webhooks)
│ ├── Bot.java # Bot initialization and client setup
│ ├── core/
│ │ ├── CommandUtils.java # Cooldown and utility helpers
│ │ ├── Emojis.java # Centralized emoji definitions
│ │ └── WebhookUtil.java # Webhook utility
│ ├── database/
│ │ └── HibernateUtil.java # Hibernate SessionFactory setup
│ ├── events/
│ │ ├── GuildCreate.java # Handler when bot joins a server
│ │ ├── GuildDelete.java # Handler when bot leaves a server
│ │ ├── InteractionCreate.java# Handles slash command interactions
│ │ ├── MessageCreate.java # Handles prefix commands
│ │ └── Ready.java # Bot ready event
│ ├── handlers/
│ │ ├── AntiCrash.java # Global error interception
│ │ └── Logger.java # Logger for bot activity
│ ├── models/
│ │ └── User.java # JPA entity for user data
│ └── commands/
│ ├── prefix/PingCommand.java # Example prefix ping command
│ └── slash/PingCommand.java # Example slash ping command
Set DB_DIALECT to one of the following:
| Dialect | DB_URL Example |
|---|---|
SQLITE |
jdbc:sqlite:discord_bot.db |
POSTGRESQL |
jdbc:postgresql://localhost:5432/discord_bot |
MYSQL |
jdbc:mysql://localhost:3306/discord_bot |
The HibernateUtil.java file dynamically configures the Hibernate SessionFactory based on DB_DIALECT:
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
var config = new Configuration();
String dialect = Config.get("DB_DIALECT");
switch (dialect.toUpperCase()) {
case "SQLITE":
config.setProperty("hibernate.dialect", "org.hibernate.community.dialect.SQLiteDialect");
config.setProperty("hibernate.connection.url", Config.get("DB_URL"));
config.setProperty("hibernate.connection.driver_class", "org.sqlite.JDBC");
break;
case "POSTGRESQL":
config.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
config.setProperty("hibernate.connection.url", Config.get("DB_URL"));
config.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
break;
case "MYSQL":
config.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
config.setProperty("hibernate.connection.url", Config.get("DB_URL"));
config.setProperty("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver");
break;
}
config.setProperty("hibernate.connection.username", Config.get("DB_USERNAME"));
config.setProperty("hibernate.connection.password", Config.get("DB_PASSWORD"));
config.setProperty("hibernate.hbm2ddl.auto", "update");
config.addAnnotatedClass(User.class);
sessionFactory = config.buildSessionFactory();
}
return sessionFactory;
}
}public static void main(String[] args) throws ExceptionCreates a JDABuilder with GatewayIntent.GUILD_MESSAGES and GatewayIntent.MESSAGE_CONTENT. Loads handlers sequentially: AntiCrash → Hibernate → slash commands → prefix commands → events → models. Logs in via jda.build(). Registers a Runtime.getRuntime().addShutdownHook for graceful shutdown.
| Key | Type | Description |
|---|---|---|
TOKEN |
String |
Discord bot token |
CLIENT_ID |
String |
Discord application client ID |
BOT_NAME |
String |
Display name for startup report |
PREFIX |
String |
Prefix for text commands |
OWNER_IDS |
String[] |
Array of bot owner Discord IDs |
DB_DIALECT |
String |
Database dialect (SQLITE, POSTGRESQL, MYSQL) |
ERROR_WEBHOOK |
String |
Webhook URL for error reports |
SLASH_WEBHOOK |
String |
Webhook URL for slash command usage |
PREFIX_WEBHOOK |
String |
Webhook URL for prefix command usage |
JOIN_WEBHOOK |
String |
Webhook URL for guild joins |
LEAVE_WEBHOOK |
String |
Webhook URL for guild leaves |
READY_WEBHOOK |
String |
Webhook URL for ready notifications |
| Event | File | Trigger |
|---|---|---|
Ready |
events/Ready.java |
Bot goes online — logs startup, sends ready webhook |
GuildJoin |
events/GuildCreate.java |
Bot joins a server — sends join webhook |
GuildLeave |
events/GuildDelete.java |
Bot leaves a server — sends leave webhook |
SlashCommandInteraction |
events/InteractionCreate.java |
Slash command used — routes to command module |
MessageReceived |
events/MessageCreate.java |
Message sent — checks prefix, routes to prefix command |
- AntiCrash — Registers
Thread.setDefaultUncaughtExceptionHandlerfor global exception interception - Logger — Writes a startup report with command/event counts, database status, and anti-crash status
- CommandUtils —
checkCooldownhelper and error formatting utilities - Emojis — Centralized emoji constants for consistent bot responses
- WebhookUtil —
sendError,sendSlash,sendPrefix,sendJoin,sendLeave,sendReadymethods via Discord webhooks
Create src/commands/slash/[Name]Command.java:
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
public class PingCommand {
public static String name = "ping";
public static String description = "Replies with Pong!";
public static void execute(SlashCommandInteractionEvent event) {
event.reply("Pong! 🏓").queue();
}
}Create src/commands/prefix/[Name]Command.java:
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
public class PingCommand {
public static String name = "ping";
public static void execute(MessageReceivedEvent event, String[] args) {
event.getChannel().sendMessage("Pong! 🏓").queue();
}
}The InteractionCreate and MessageCreate event handlers automatically discover and register new commands via reflection on the next restart. No manual wiring is needed.
A MongoDB variant of this handler is available for teams that prefer a document database:
It replaces database/HibernateUtil.java with a MongoDB driver connection (via mongodb-driver-sync) and swaps JPA entities for BSON documents. All other modules — events, commands, handlers, core utilities — remain identical.
The Discord Handler ecosystem spans 26 repositories across 13 languages, each available in both MongoDB and Sequelize editions.
| Language | Repository |
|---|---|
| C++ | RealMtrx/Discord-Handler-Cpp |
| C# | RealMtrx/Discord-Handler-Cs |
| Dart | RealMtrx/Discord-Handler-Dart |
| Go | RealMtrx/Discord-Handler-Go |
| Java | RealMtrx/Discord-Handler-Java |
| JavaScript | RealMtrx/Discord-Handler-Js |
| Kotlin | RealMtrx/Discord-Handler-Kt |
| Lua | RealMtrx/Discord-Handler-Lua |
| PHP | RealMtrx/Discord-Handler-Php |
| Python | RealMtrx/Discord-Handler-Py |
| Ruby | RealMtrx/Discord-Handler-Rb |
| Rust | RealMtrx/Discord-Handler-Rs |
| TypeScript | RealMtrx/Discord-Handler ← hub |
RealMtrx/Discord-Handler — the TypeScript hub and flagship repository. Star it to support the ecosystem.
Distributed under the MIT License. See LICENSE for more information.
Built by Mtrx — Discord: 0hu2 — RealMtrx/Discord-Handler