Quarkus Extension: CDI Integration for Morphium

quarkus-morphium is an optional Morphium module that integrates Morphium into Quarkus applications via a CDI producer, type-safe @ConfigMapping configuration, declarative transactions, health checks, Dev Services, Dev UI integration, and GraalVM native-image support. It also pulls in morphium-jakarta-data and generates Jakarta Data @Repository implementations at build time via Gizmo bytecode generation — no runtime reflection, no dynamic proxies.

!!! note "Optional module — the Morphium core does not depend on it" de.caluga:morphium has zero compile- or runtime dependency on this extension, on Quarkus, or on jakarta.data-api. Building the Morphium reactor without this module (-DskipExtensions) produces an unchanged core. You only need quarkus-morphium if you are building a Quarkus application against MongoDB via Morphium.

What it provides

  • CDI producer@Inject Morphium morphium; anywhere in a Quarkus bean, backed by a single, application-scoped Morphium instance configured from application.properties.
  • Type-safe configuration — every setting lives under quarkus.morphium.* as a @ConfigMapping, validated at build time instead of failing at runtime on a typo.
  • Declarative transactions@MorphiumTransactional on a CDI bean method wraps the method body in startTransaction()/commitTransaction()/abortTransaction() automatically, with MorphiumTransactionEvent CDI events (BEFORE_COMMIT, AFTER_COMMIT, AFTER_ROLLBACK) for cross-cutting reactions (audit logging, outbox publishing, etc.). Gracefully degrades to non-transactional execution on Azure CosmosDB, which is auto-detected.
  • Jakarta Data repositories — declare a @Repository interface extending CrudRepository/MorphiumRepository from morphium-jakarta-data; the extension's build-time processor generates the implementation via Gizmo, with no reflection at runtime. See Jakarta Data for the full query-derivation, JDQL, and pagination feature set — everything documented there works identically once generated by this extension.
  • Health checks — MicroProfile liveness (/q/health/live), readiness (/q/health/ready, with connection-pool metadata), and startup (/q/health/started) probes registered automatically via SmallRye Health.
  • Dev Services — a MongoDB container (optionally as a single-node replica set, so transactions and change streams work out of the box) starts automatically in dev and test mode when no explicit quarkus.morphium.hosts is configured — no Docker Compose, no manual setup.
  • Dev UI card — live MongoDB connection info (hosts, database, replica-set mode, container ID) at /q/dev-ui/.
  • GraalVM native-image support — every @Entity/@Embedded class (and Morphium's own reflection-dependent internals) is registered for reflection at build time; no manual reflect-config.json.
  • MorphiumId JSON serialization — entities with @Id MorphiumId id serialize to a plain 24-character hex string over REST (both Jackson and JSON-B), and parse back from one — no serializer to write by hand.
  • Migration runner — a lightweight, MongoDB-backed schema/data migration mechanism (quarkus.morphium.migration.*) with a distributed lock, so multiple application instances don't race to apply the same migration.

Installation

<dependency>
  <groupId>de.caluga</groupId>
  <artifactId>quarkus-morphium</artifactId>
  <version>${project.version}</version>
</dependency>

In the Morphium reactor, ${project.version} resolves to whatever version the reactor is currently on (see the root pom.xml). This module follows Morphium's regular release versioning; there is no separate version line to track — building the reactor (mvn -pl quarkus-morphium -am verify) builds this extension against the exact Morphium core version in the same build.

Configuration Reference

All properties live under quarkus.morphium.*. This is not the complete list — see the Antora documentation in the module directory (quarkus-morphium/docs/) for every property — but covers the most commonly used ones, each verified directly against the @ConfigMapping source.

PropertyDefaultDescriptionSource
quarkus.morphium.hostslocalhost:27017Comma-separated host:port listMorphiumRuntimeConfig.java:52
quarkus.morphium.database(required)MongoDB database nameMorphiumRuntimeConfig.java:55
quarkus.morphium.username / .password--Optional credentialsMorphiumRuntimeConfig.java:58,61
quarkus.morphium.auth-databaseadminAuthentication databaseMorphiumRuntimeConfig.java:65
quarkus.morphium.read-preferenceprimaryRead preferenceMorphiumRuntimeConfig.java:73
quarkus.morphium.index-checkcreate-on-startupIndex management strategy (create-on-startup, warn-on-startup, create-on-write-new-col, no-check)MorphiumRuntimeConfig.java:92
quarkus.morphium.max-connections250Connection pool sizeMorphiumRuntimeConfig.java:108
quarkus.morphium.max-wait-time2000Max wait time (ms) for a pooled connectionMorphiumRuntimeConfig.java:118
quarkus.morphium.default-query-timeout-ms0 (disabled)Server-side maxTimeMS applied to queries without an explicit per-query timeoutMorphiumRuntimeConfig.java:133
quarkus.morphium.atlas-url--MongoDB Atlas SRV connection string (overrides hosts)MorphiumRuntimeConfig.java:139
quarkus.morphium.driver-namePooledDriverPooledDriver (production) or InMemDriver (tests, no MongoDB needed)MorphiumRuntimeConfig.java:146
quarkus.morphium.replica-set-name--MongoDB replica set name (required for transactions)MorphiumRuntimeConfig.java:153
quarkus.morphium.connect-retries5Connection attempts before giving upMorphiumRuntimeConfig.java:162
quarkus.morphium.cache.read-cache-enabledtrueEnable query result cacheCacheConfig.java:31
quarkus.morphium.cache.global-valid-time60000Cache TTL in millisecondsCacheConfig.java:27
quarkus.morphium.local-date-time.use-bson-date--Store LocalDateTime as BSON ISODateLocalDateTimeConfig.java
quarkus.morphium.ssl.enabledfalseEnable TLSSslConfig.java:48
quarkus.morphium.ssl.auth-mechanism--MONGODB-X509 for client-certificate authSslConfig.java:59
quarkus.morphium.ssl.keystore-path / .keystore-password--Keystore for client-cert auth / mutual TLSSslConfig.java:65,68
quarkus.morphium.ssl.truststore-path / .truststore-password--Truststore for server certificate validationSslConfig.java:74,77
quarkus.morphium.ssl.invalid-hostname-allowedfalseAllow invalid hostnames (dev only)SslConfig.java:84
quarkus.morphium.ssl.tls-configuration-name--Use a named Quarkus TLS registry configuration instead of explicit keystore/truststore pathsSslConfig.java:108
quarkus.morphium.devservices.enabledtrueEnable automatic MongoDB container in dev/test modeMorphiumDevServicesBuildTimeConfig.java:45
quarkus.morphium.devservices.image-namemongo:8Docker image for Dev ServicesMorphiumDevServicesBuildTimeConfig.java:52
quarkus.morphium.devservices.database-namemorphium-devDatabase name injected by Dev ServicesMorphiumDevServicesBuildTimeConfig.java:59
quarkus.morphium.devservices.replica-settrueStart MongoDB as a single-node replica set (enables transactions)MorphiumDevServicesBuildTimeConfig.java:72
quarkus.morphium.health.enabledtrueEnable liveness/readiness/startup health checksMorphiumHealthBuildTimeConfig.java:41
quarkus.morphium.migration.migrate-at-startfalseRun pending migrations automatically on startupMorphiumMigrationConfig.java:40
quarkus.morphium.migration.change-log-collectionmorphiumChangeLogCollection tracking executed migrationsMorphiumMigrationConfig.java:44
quarkus.morphium.migration.lock-collectionmorphiumMigrationLockCollection used for the distributed migration lockMorphiumMigrationConfig.java:48
quarkus.morphium.migration.lock-ttl-seconds60Migration-lock TTL in secondsMorphiumMigrationConfig.java:56

Quick Example

@Entity(collectionName = "products")
public class Product {
    @Id private MorphiumId id;
    private String name;
    private double price;
    private String category;
    @Version private long version;
    // getters/setters omitted
}

@Repository
public interface ProductRepository extends MorphiumRepository<Product, MorphiumId> {
    List<Product> findByCategory(String category);

    @OrderBy("price")
    List<Product> findByPriceGreaterThan(double minPrice);
}

@ApplicationScoped
public class ProductService {
    @Inject ProductRepository products;

    @MorphiumTransactional
    public Product create(String name, double price, String category) {
        var p = new Product();
        p.setName(name);
        p.setPrice(price);
        p.setCategory(category);
        return products.insert(p);
    }
}
quarkus.morphium.database=my-app-db
# Dev Services starts MongoDB automatically — no further config needed in dev/test.

Testing without Docker

%test.quarkus.morphium.driver-name=InMemDriver
%test.quarkus.morphium.database=test-db

InMemDriver is Morphium's in-memory MongoDB emulation — @QuarkusTest classes run against it with no container and no external MongoDB, exactly like the core Morphium test suite.

Full Documentation

This page is an overview. The complete documentation — getting started, entity mapping, configuration reference, transactions, health checks, Dev Services, Jakarta Data repositories, testing, and advanced topics — lives as an Antora documentation module in the repository, at quarkus-morphium/docs/ (source pages under quarkus-morphium/docs/modules/ROOT/pages/):

quarkus-morphium/docs/modules/ROOT/pages/

!!! note "Antora docs are not part of this site's build" This MkDocs site (the pages under docs/, including this one) and the Antora documentation under quarkus-morphium/docs/ are two separate, coexisting toolchains — the Antora source is not currently built or published by this repository's deploy-docs.yml workflow. Until a publishing decision is made, browse the Antora pages directly on GitHub via the link above, or render them locally with the Antora CLI from quarkus-morphium/docs/antora.yml.

See also Jakarta Data for the framework-agnostic repository runtime that this extension builds on, and PoppyDB for Morphium's other optional module.

← Back to Documentation Hub