An interactive database data dictionary application built with Java 21 and Spring Boot 3.4. It connects to PostgreSQL and SQL Server databases, introspects their schemas, and presents a browsable catalog of tables, columns, indexes, constraints, foreign keys, and ER diagrams.
| Layer | Technology |
|---|---|
| Language | Java 21 |
| Framework | Spring Boot 3.4.1 (Web, Data JPA, Security) |
| Templates | Thymeleaf 3.1 + Layout Dialect 3.4 |
| App Database | H2 (file-based, ./data/dictionary) |
| Build | Gradle Kotlin DSL (wrapper included) |
| Diagrams | Mermaid.js v10 (CDN) |
| Containers | Docker multi-stage build, Docker Compose |
| Target DBs | PostgreSQL 16, SQL Server 2022 |
- Schema Sync — CLI command to introspect target databases and store metadata in H2
- Dashboard — Lists all synced databases with table counts and health indicators
- Database Detail — Tables grouped by schema with row counts, PCI/PII flags, and incoming references
- Table Detail — Columns, indexes, constraints, foreign keys, and inline ER diagrams
- ER Diagrams — Full database and per-table diagrams rendered with Mermaid.js
- Search — Full-text search across tables and columns
- PCI/PII Tracking — Auto-detected and manual classification with override support
- Admin Panel — Inline editing of descriptions, notes, glossary, and PCI/PII tags
- Change Log — Tracks schema changes between sync runs
- Export — Markdown export for tables and full databases
- Java 21 (JDK)
- Docker & Docker Compose (for target databases)
docker compose up -d postgres mssql mssql-initThis starts PostgreSQL 16 (port 5432) and SQL Server 2022 (port 1433) with sample schemas pre-loaded.
# Windows
.\gradlew.bat bootRun
# Linux / macOS
./gradlew bootRunThe app starts on http://localhost:3000.
# Windows
.\gradlew.bat bootRun --args="--sync"
# Linux / macOS
./gradlew bootRun --args="--sync"This introspects all configured target databases and stores metadata in the H2 database.
Navigate to http://localhost:3000/admin/login and enter password: admin
Once logged in you can edit table/column descriptions, set PCI/PII classifications, and update database notes and glossary entries inline.
# Build and start everything (app + databases)
docker compose up -d --build
# View logs
docker compose logs -f app
# Stop all services
docker compose downThe app runs at http://localhost:3000 inside the container. Data is persisted in Docker volumes (app-data, pg-data, mssql-data).
All settings are in src/main/resources/application.properties. Key environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Application port |
ADMIN_PASSWORD |
admin |
Admin password (plaintext or BCrypt hash) |
DB_ENGINE_1 |
postgres |
Engine type (postgres or mssql) |
DB_HOST_1 |
localhost |
Target database host |
DB_PORT_1 |
5432 |
Target database port |
DB_NAME_1 |
sampledb |
Target database name |
DB_USER_1 |
postgres |
Target database user |
DB_PASS_1 |
postgres |
Target database password |
SCHEMA_INCLUDE |
(empty = all) | Comma-separated schemas to include |
SCHEMA_EXCLUDE |
(empty = none) | Comma-separated schemas to exclude |
Add more connections by incrementing the suffix: DB_ENGINE_2, DB_HOST_2, etc.
src/main/java/com/datadictionary/
├── DataDictionaryApplication.java # Entry point + CLI sync runner
├── config/
│ └── SecurityConfig.java # Spring Security (permit all, CSRF config)
├── controller/
│ ├── AdminController.java # Admin login, API endpoints for editing
│ ├── DatabaseController.java # Dashboard, DB detail, diagrams, PCI/PII pages
│ ├── DiagramController.java # ER diagram JSON API
│ ├── ExportController.java # Markdown export endpoints
│ └── SearchController.java # Search page
├── entity/ # JPA entities (10 tables)
├── repository/ # Spring Data JPA repositories
└── service/
├── DatabaseService.java # DB introspection & sync logic
└── SearchService.java # JDBC-based search
src/main/resources/
├── application.properties # App configuration
├── schema.sql # H2 schema DDL
├── templates/ # Thymeleaf templates
│ ├── layout.html # Base layout
│ ├── dashboard.html # Home page
│ ├── database.html # Database detail
│ ├── table-detail.html # Table detail
│ ├── search.html # Search results
│ └── ... # Other pages
└── static/
├── css/style.css # Styles
└── js/
├── admin.js # Inline editing & PCI/PII modal
└── diagram.js # Mermaid ER diagram rendering
The application stores all its data in an H2 file database at ./data/dictionary. The H2 files are:
data/dictionary.mv.db— Main data filedata/dictionary.trace.db— Trace/log file (optional, can be deleted)
Stop the application first, then copy the database files:
# Stop the app (Ctrl+C if running in terminal)
# Windows
mkdir backup
copy data\dictionary.mv.db backup\dictionary.mv.db
# Linux / macOS
mkdir -p backup
cp data/dictionary.mv.db backup/dictionary.mv.dbH2 in AUTO_SERVER mode supports safe file copy while running, but stopping the app first is safer:
# Windows
copy data\dictionary.mv.db backup\dictionary_%date:~-4%%date:~4,2%%date:~7,2%.mv.db
# Linux / macOS
cp data/dictionary.mv.db backup/dictionary_$(date +%Y%m%d).mv.db# Windows
java -cp build/libs/*.jar org.h2.tools.Script ^
-url "jdbc:h2:file:./data/dictionary" -user sa -script backup/dump.sql
# Linux / macOS
java -cp build/libs/*.jar org.h2.tools.Script \
-url "jdbc:h2:file:./data/dictionary" -user sa -script backup/dump.sqlThis creates a full SQL dump that can be used for migration or archival.
If running via Docker Compose, back up the app-data volume:
docker run --rm -v data-dictionary-java_app-data:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/dictionary-backup.tar.gz -C /data .# Stop the app first
# Windows
copy backup\dictionary.mv.db data\dictionary.mv.db
# Linux / macOS
cp backup/dictionary.mv.db data/dictionary.mv.dbDelete the existing database files, then run the dump:
# Remove old data
rm data/dictionary.mv.db
# Windows
java -cp build/libs/*.jar org.h2.tools.RunScript ^
-url "jdbc:h2:file:./data/dictionary" -user sa -script backup/dump.sql
# Linux / macOS
java -cp build/libs/*.jar org.h2.tools.RunScript \
-url "jdbc:h2:file:./data/dictionary" -user sa -script backup/dump.sqldocker compose down
docker run --rm -v data-dictionary-java_app-data:/data -v $(pwd)/backup:/backup \
alpine sh -c "rm -rf /data/* && tar xzf /backup/dictionary-backup.tar.gz -C /data"
docker compose up -d| URL | Description |
|---|---|
/ |
Dashboard — all synced databases |
/db/{id} |
Database detail — tables by schema |
/table/{id} |
Table detail — columns, FKs, indexes |
/diagram/{dbId} |
Full ER diagram for a database |
/search?q=... |
Search tables and columns |
/pci-pii/{dbId} |
PCI/PII flagged columns |
/relationships/{dbId} |
Foreign key relationships |
/changes/{dbName} |
Schema change log |
/glossary/{dbId} |
Database glossary |
/overview/{dbId} |
Database overview & admin notes |
/admin/login |
Admin login |
/admin/connections |
Manage database connections |
/export/md/table/{id} |
Export table as Markdown |
/export/md/db/{id} |
Export full database as Markdown |