| Category | Badges |
|---|---|
| License | |
| Build | |
| Stack | |
| Databases | |
| Status |
Lightweight Reactive ORM for Java 21
JPA-style annotations · R2DBC-native · Pluggable dialects
Nova is a lightweight reactive ORM built on R2DBC and Project Reactor.
It keeps the JPA-style annotation model that Java developers already know
while exposing every persistence API as Mono / Flux, so it fits naturally
into non-blocking data pipelines. Nova avoids the persistence-context,
first-level-cache, and lazy-loading complexity of full-stack ORMs, and the
core module depends only on the R2DBC SPI.
Nova is not a streaming framework, a query builder for arbitrary SQL, or a drop-in replacement for JPA. The goal is a small-surface-area reactive data-access layer.
// build.gradle.kts
repositories { mavenCentral() }
dependencies {
implementation("io.github.bssm-oss:nova:1.0.1")
runtimeOnly("io.r2dbc:r2dbc-h2:1.0.0.RELEASE")
// runtimeOnly("org.postgresql:r2dbc-postgresql:1.0.7.RELEASE")
}import io.nova.Nova;
import io.nova.core.ReactiveEntityOperations;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
@Entity
@Table(name = "accounts")
public class Account {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Column(name = "email_address") private String email;
public Account() {}
public Account(Long id, String email) { this.id = id; this.email = email; }
// getters/setters...
}
ConnectionFactory cf = ConnectionFactories.get(
"r2dbc:h2:mem:///nova-smoke?options=DB_CLOSE_DELAY=-1");
ReactiveEntityOperations operations = Nova.create(cf);
Nova.schemaInitializer(cf).create(Account.class)
.then(operations.save(new Account(null, "user@example.com")))
.flatMap(saved -> operations.findById(Account.class, saved.getId()))
.subscribe(System.out::println);Nova.create(cf) and Nova.schemaInitializer(cf) auto-detect the dialect (PostgreSQL / MySQL / MariaDB / H2 / Oracle) from the R2DBC driver metadata. In Spring Boot, the starter wires both beans automatically and supports JPA-style nova.ddl-auto=create-drop. See Getting started for details.
| Document | Contents |
|---|---|
| Getting started | Installation, first entity, Nova.create(...), schema initialization |
| Entities | Annotations, composite types, relationships, indexes |
| Queries | CRUD, Query DSL, Updater, Projection, Aggregations, Page/Slice, Cursor |
| Transactions | Propagation / isolation, pessimistic locking, retry |
| Dialects & Schema | Dialect SPI, the five bundled dialects, SchemaGenerator, migration |
| Spring | Spring Boot starter, nova-spring-data repositories |
| Observability | SqlExecutionListener, Micrometer adapter, pool reachability |
Full documentation index: docs/.
| Version | Notes | |
|---|---|---|
| Java | 21 | Resolved by Gradle Toolchains |
| Build | Gradle 8.10+ | Wrapper (./gradlew) included |
| Reactive Runtime | Project Reactor 3.7.x | |
| Driver SPI | R2DBC SPI 1.0.0.RELEASE | |
| PostgreSQL | 14, 15, 16, 17 | nova-dialect-postgresql |
| MySQL | 8.0, 8.4 | nova-dialect-mysql |
| MariaDB | 10.5+, 11 | nova-dialect-mariadb |
| H2 | 2.x | nova-dialect-h2 |
| Oracle | 12c+, 19c, 21c+ | nova-dialect-oracle |
Nova core depends only on the R2DBC SPI. Add the matching R2DBC driver (r2dbc-postgresql, r2dbc-mysql, etc.) as a separate runtime dependency.
| Module | Description |
|---|---|
nova |
aggregate — core + r2dbc + every bundled dialect |
nova-core |
Annotations, metadata, query DSL, SQL rendering, transactions, ReactiveEntityOperations, and other core abstractions |
nova-r2dbc |
R2DBC SPI adapter — R2dbcSqlExecutor, R2dbcTransactionManager, SqlExecutionListener hooks |
nova-dialect-postgresql |
PostgreSQL dialect ($N bind marker, bigserial, RETURNING) |
nova-dialect-mysql |
MySQL dialect (? bind marker, auto_increment) |
nova-dialect-h2 |
H2 dialect (GENERATED ALWAYS AS IDENTITY) |
nova-dialect-mariadb |
MariaDB dialect |
nova-dialect-oracle |
Oracle dialect (OFFSET..FETCH, <seq>.nextval from dual) |
nova-spring-boot-starter |
Spring Boot auto-configuration — dialect auto-detect, nova.* properties |
nova-spring-data |
Spring Data-style ReactiveCrudRepository<T, ID> + @EnableNovaRepositories |
nova-metrics-micrometer |
Micrometer adapter (MicrometerSqlExecutionListener) |
Maven coordinates stay flat under io.github.bssm-oss:<module>:1.0.1.
./gradlew build # full build + tests
./gradlew test # tests only
./gradlew clean build # clean rebuildThe Gradle Wrapper (./gradlew) is bundled — no separate Gradle install is required.
- Optimistic locking (
@Version) — Long / Integer / Short, surfacesOptimisticLockingFailureExceptionon conflict - Soft delete (
@SoftDelete) — rewrites DELETE as UPDATE; SELECT gets an automatic alive guard - Audit fields (
@CreatedAt/@UpdatedAt) — injectableClock - Entity lifecycle callbacks (
@PrePersist/@PostPersist/@PreUpdate/@PostUpdate/@PostLoad/@PreRemove/@PostRemove) - Updater builder DSL — criteria-based partial UPDATE without an entity instance
- Projections (record / DTO mapping)
- Aggregations (
count/countDistinct/sum/avg/min/max+groupBy+having) - Cursor / keyset pagination
- NativeQuery — raw SQL entry point
- CompiledQuery — render SQL once, swap bindings
- SQL execution hook (
SqlExecutionListener,SlowQueryLoggingListener) - Transaction propagation / isolation / readOnly hints
- SEQUENCE / UUID id generation
- Batch insert with generated-id recovery
-
@Embeddable/@Embeddedcomposite value types - Table-level
@Index/@UniqueConstraint - Schema migration helpers (
createIndexes,alterTableAddColumn,alterTableDropColumn) - H2 / MariaDB / Oracle dialects
- Spring Boot auto-configuration (
nova-spring-boot-starter) with dialect auto-detect - Pessimistic locking (
QuerySpec.forUpdate()/forShare()) - Metrics adapter (
nova-metrics-micrometer— Micrometer) - Retry helper (
ReactiveRetryTemplate— exponential backoff + jitter) - FetchGroup DSL + relationship mapping (
@ManyToOne/@OneToManyautomatic hydration) -
Page/Sliceresult types +PageRequestpage-number-friendly API - Spring Data-style repositories (
nova-spring-data, no dependency on Spring Data Commons) - JSON column type (
@Json— pluggableJsonCodecSPI) -
@Column(length / precision / scale)andBigDecimalcolumns - 1.0 GA released to Maven Central (
io.github.bssm-oss:nova:1.0.0— all 11 modules published)
For in-flight and proposed items, see the issue tracker.
Contributions are welcome.
- Open an issue first to agree on scope and direction.
- Branch off
mainand keep PRs small and focused on a single concern. - Run
./gradlew buildand confirm every test passes. - Follow Conventional Commits for commit messages.
The full guide — issue / PR / commit conventions and merge policy — is in CONTRIBUTING.md.
Nova is released under the Apache License 2.0.
Copyright (c) Nova contributors
Licensed under the Apache License, Version 2.0