Database

Obsidian uses ActiveJDBC as its ORM layer and HikariCP for connection pooling. The connection is managed automatically — no manual wrapping required.

Supported databases
Database DB_TYPE Notes
SQLite sqlite File-based, no pooling. Perfect for development and small apps.
MySQL mysql HikariCP connection pooling included.
PostgreSQL postgresql HikariCP connection pooling included.
Environment configuration

Obsidian uses dotenv-java to load credentials from a .env file at your project root.

SQLite
ENVIRONMENT=development
PORT_WEB=8080

DB_TYPE=sqlite
DB_PATH=database.db
MySQL
ENVIRONMENT=development
PORT_WEB=8080

DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_database
DB_USER=root
DB_PASSWORD=secret
PostgreSQL
ENVIRONMENT=development
PORT_WEB=8080

DB_TYPE=postgresql
DB_HOST=localhost
DB_PORT=5432
DB_NAME=my_database
DB_USER=postgres
DB_PASSWORD=secret
Security warning
Never commit your .env file to version control. Add it to .gitignore.
Automatic connection management

Since Obsidian 1.3.0, the framework automatically opens and closes the ActiveJDBC thread-local connection around every request via two built-in middlewares — DatabaseMiddleware and DatabaseCloseMiddleware.

Before 1.3.0
public List<Article> findAll() {
    return DB.withConnection(() -> Article.findAll().stream().toList());
}
Now
public List<Article> findAll() {
    return Article.findAll().stream().toList();
}
Transactions

Use DB.withTransaction() for atomic operations. Changes are committed on success and rolled back on error.

DB.withTransaction(() -> {
    User sender = User.findById(senderId);
    User receiver = User.findById(receiverId);

    if (sender.getBigDecimal("balance").compareTo(amount) < 0) {
        throw new IllegalStateException("Insufficient balance");
    }

    sender.set("balance", sender.getBigDecimal("balance").subtract(amount));
    receiver.set("balance", receiver.getBigDecimal("balance").add(amount));

    sender.saveIt();
    receiver.saveIt();

    return true;
});
Connection pool (MySQL / PostgreSQL)

HikariCP is automatically configured with these defaults:

Maximum pool size 20 connections
Minimum idle 5 connections
Auto-commit Disabled (managed by ActiveJDBC)

SQLite uses direct JDBC connections without pooling.