PolyDb is a lightweight Java persistence framework for working with databases using annotations, automatic schema generation, repository-based queries, and migrations. It is designed to keep the setup simple while still providing a structured and extensible way to map Java entities to database tables.
- Annotation-based entity mapping
- Automatic schema generation
- Repository-style CRUD access
- Database dialect support
- Java-based migrations
- Support for multiple databases
- Simple bootstrap API
- Java 17
- Maven
- A supported database
- A JDBC driver for your database
package de.tnttastisch.polydb.examples.entity;
import de.tnttastisch.polydb.core.annotations.*;
import java.time.OffsetDateTime;
import java.util.UUID;
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "username", length = 50)
@Unique
private String username;
@Column(name = "email")
private String email;
@Column(name = "created_at")
private OffsetDateTime createdAt;
public User() {
}
public User(UUID id, String username, String email, LocalDateTime createdAt) {
this.id = id;
this.username = username;
this.email = email;
this.createdAt = createdAt;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
}PolyDB polyDB = PolyDB.builder()
.url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1")
.username("sa")
.password("")
.entityPackage("de.tnttastisch.polydb.examples.entity")
.autoMigration(true)
.start();Repository<User> userRepository = polyDB.repository(User.class);
User user = new User();
user.setId(UUID.randomUUID());
user.setUsername("TntTastisch");
user.setEmail("info@tnttastisch.de");
user.setCreatedAt(LocalDateTime.now());
userRepository.save(user);
List<User> users = userRepository.findAll();
for (User u : users) {
System.out.println("Found user: " + u.getUsername() + " (" + u.getEmail() + ")");
}The polydb-examples module contains a simple working example application that:
- starts PolyDb
- creates a repository
- saves a user
- reads users back from the database
This is a good starting point if you want to understand the framework structure quickly.
Marks a class as a database entity.
Defines the table name.
Marks the primary key field.
Defines column metadata such as name, length, nullability, precision, and scale.
Marks a column as unique.
Defines an index on a class or field.
PolyDb provides a simple repository abstraction:
public interface Repository<T> {
void save(T entity);
Optional<T> findById(Object id);
List<T> findAll();
void delete(T entity);
void deleteById(Object id);
}Optional<User> user = userRepository.findById(id);
userRepository.deleteById(id);PolyDb supports Java-based migrations.
Example migration:
package de.tnttastisch.polydb.examples.entity.migrations;
import de.tnttastisch.polydb.migration.core.Migration;
import de.tnttastisch.polydb.migration.core.MigrationContext;
import java.sql.Connection;
import java.sql.Statement;
public class V1_InitialDataMigration implements Migration {
@Override
public String getVersion() {
return "1";
}
@Override
public String getDescription() {
return "Inserts initial system user";
}
@Override
public void migrate(MigrationContext context) throws Exception {
try (Connection conn = context.getDataSource().getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute("INSERT INTO users (id, username, email, created_at) VALUES ('00000000-0000-0000-0000-000000000000', 'SYSTEM', 'system@polydb.org', NOW())");
}
}
}Migrations are scanned automatically from the .migrations package inside your entity package.
PolyDb includes dialect support for:
- H2
- MySQL
- MariaDB
- PostgreSQL
- SQLite
- Oracle
- SQL Server
- Firebird
- DB2
- MongoDB
- Cassandra
To build the whole project:
mvn clean installTo run the example module:
mvn -pl polydb-examples -am exec:javaA typical PolyDb setup looks like this:
- Define entities with annotations
- Configure PolyDb with a database URL
- Enable automatic schema sync
- Run migrations
- Use repositories for data access
- Repository: https://repo.tnttastisch.de
- Example module:
polydb-core - Main entry point:
PolyDB.builder()
<repository>
<id>tnttastisch-repo-releases</id>
<name>TntTastisch Repository</name>
<url>https://repo.tnttastisch.de/releases</url>
</repository>
<dependency>
<groupId>de.tnttastisch</groupId>
<artifactId>polydb-core</artifactId>
<version>${current_version}</version>
</dependency>Contributions, issues, and suggestions are welcome.
If you add new features, please include:
- tests
- documentation
- example usage where appropriate