Skip to content

bssm-oss/nova-reactive

Repository files navigation

Nova

Category Badges
License License
Build Java Gradle Kotlin DSL
Stack Reactor R2DBC
Databases PostgreSQL MySQL
Status 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.


Quick start

// 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.


Documentation

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/.


Requirements

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.


Modules

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.


Building from source

./gradlew build          # full build + tests
./gradlew test           # tests only
./gradlew clean build    # clean rebuild

The Gradle Wrapper (./gradlew) is bundled — no separate Gradle install is required.


Roadmap

  • Optimistic locking (@Version) — Long / Integer / Short, surfaces OptimisticLockingFailureException on conflict
  • Soft delete (@SoftDelete) — rewrites DELETE as UPDATE; SELECT gets an automatic alive guard
  • Audit fields (@CreatedAt / @UpdatedAt) — injectable Clock
  • 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 / @Embedded composite 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 / @OneToMany automatic hydration)
  • Page / Slice result types + PageRequest page-number-friendly API
  • Spring Data-style repositories (nova-spring-data, no dependency on Spring Data Commons)
  • JSON column type (@Json — pluggable JsonCodec SPI)
  • @Column(length / precision / scale) and BigDecimal columns
  • 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.


Contributing

Contributions are welcome.

  1. Open an issue first to agree on scope and direction.
  2. Branch off main and keep PRs small and focused on a single concern.
  3. Run ./gradlew build and confirm every test passes.
  4. Follow Conventional Commits for commit messages.

The full guide — issue / PR / commit conventions and merge policy — is in CONTRIBUTING.md.


License

Nova is released under the Apache License 2.0.

Copyright (c) Nova contributors
Licensed under the Apache License, Version 2.0

About

reactive JPA - nova-reactive 동기 JPA처럼 사용하기 쉬운 비동기 JPA 라이브러리 입니다.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages